Navigation

Main Page
Download
Support
Installation
Tutorial
Examples
Reference Manual
   Version 1.0.4
   Version 1.0.4dev
      Class Index
      File List
Publications


Hosted by Get Ion Beam Simulator at SourceForge.net. Fast, secure and Free Open Source software downloads

particles.hpp

Go to the documentation of this file.
00001 
00005 /* Copyright (c) 2005-2011 Taneli Kalvas. All rights reserved.
00006  *
00007  * You can redistribute this software and/or modify it under the terms
00008  * of the GNU General Public License as published by the Free Software
00009  * Foundation; either version 2 of the License, or (at your option)
00010  * any later version.
00011  * 
00012  * This library is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00015  * General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with this library (file "COPYING" included in the package);
00019  * if not, write to the Free Software Foundation, Inc., 51 Franklin
00020  * Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  * 
00022  * If you have questions about your rights to use or distribute this
00023  * software, please contact Berkeley Lab's Technology Transfer
00024  * Department at TTD@lbl.gov. Other questions, comments and bug
00025  * reports should be sent directly to the author via email at
00026  * taneli.kalvas@jyu.fi.
00027  * 
00028  * NOTICE. This software was developed under partial funding from the
00029  * U.S.  Department of Energy.  As such, the U.S. Government has been
00030  * granted for itself and others acting on its behalf a paid-up,
00031  * nonexclusive, irrevocable, worldwide license in the Software to
00032  * reproduce, prepare derivative works, and perform publicly and
00033  * display publicly.  Beginning five (5) years after the date
00034  * permission to assert copyright is obtained from the U.S. Department
00035  * of Energy, and subject to any subsequent five (5) year renewals,
00036  * the U.S. Government is granted for itself and others acting on its
00037  * behalf a paid-up, nonexclusive, irrevocable, worldwide license in
00038  * the Software to reproduce, prepare derivative works, distribute
00039  * copies to the public, perform publicly and display publicly, and to
00040  * permit others to do so.
00041  */
00042 
00043 #ifndef PARTICLES_HPP
00044 #define PARTICLES_HPP 1
00045 
00046 
00047 #include <vector>
00048 #include <string>
00049 #include <gsl/gsl_errno.h>
00050 #include "geometry.hpp"
00051 #include "scalarfield.hpp"
00052 #include "vectorfield.hpp"
00053 #include "vec3d.hpp"
00054 #include "callback.hpp"
00055 
00056 
00057 /* Integer error value that is supposed to diffed from internal GSL error values */
00058 #define IBSIMU_DERIV_ERROR 201
00059 
00060 
00068 enum particle_status_e {
00069     PARTICLE_OK = 0,
00070     PARTICLE_OUT,
00071     PARTICLE_COLL,
00072     PARTICLE_BADDEF,
00073     PARTICLE_TIME,
00074     PARTICLE_NSTP 
00075 };
00076 
00077 
00078 
00079 /* ************************************************************************************* *
00080  * Particle point classes                                                                *
00081  * ************************************************************************************* */
00082 
00083 
00088 class ParticlePBase
00089 {
00090 
00091 };
00092 
00093 
00099 class ParticleP2D : public ParticlePBase 
00100 {
00101     double         _x[5];   
00103 public:
00104 
00107     ParticleP2D() {}
00108 
00111     ParticleP2D( double t, double x, double vx, double y, double vy ) {
00112         _x[0] = t; _x[1] = x; _x[2] = vx; _x[3] = y; _x[4] = vy;
00113     }
00114 
00117     ParticleP2D( std::istream &s ) {
00118         _x[0] = read_double( s );
00119         _x[1] = read_double( s );
00120         _x[2] = read_double( s );
00121         _x[3] = read_double( s );
00122         _x[4] = read_double( s );
00123     }
00124 
00127     static geom_mode_e geom_mode() { return(MODE_2D); }
00128 
00131     static size_t dim() { return(2); }
00132 
00135     static size_t size() { return(5); }
00136 
00148     static int get_derivatives( double t, const double *x, double *dxdt, void *data );
00149 
00154     static int trajectory_intersections_at_plane( std::vector<ParticleP2D> &intsc, 
00155                                                   int crd, double val,
00156                                                   const ParticleP2D &x1, 
00157                                                   const ParticleP2D &x2,
00158                                                   int extrapolate = 0 );
00159 
00164     static const std::string IQ_unit() { return( "A/m" ); }
00165 
00168     Vec3D location() const { return( Vec3D( _x[1], _x[3], 0.0 ) ); }
00169 
00172     Vec3D velocity() const { return( Vec3D( _x[2], _x[4], 0.0 ) ); }
00173 
00176     double speed() { return( sqrt(_x[2]*_x[2] + _x[4]*_x[4]) ); }
00177 
00180     double &operator[]( int i ) { return( _x[i] ); }
00181 
00184     const double &operator[]( int i ) const { return( _x[i] ); }
00185 
00188     double &operator()( int i ) { return( _x[i] ); }
00189 
00192     const double &operator()( int i ) const { return( _x[i] ); }
00193 
00194     ParticleP2D operator+( const ParticleP2D &pp ) const { 
00195         ParticleP2D res;
00196         res[0] = _x[0] + pp[0];
00197         res[1] = _x[1] + pp[1];
00198         res[2] = _x[2] + pp[2];
00199         res[3] = _x[3] + pp[3];
00200         res[4] = _x[4] + pp[4];
00201         return( res );
00202     }
00203 
00204     ParticleP2D operator-( const ParticleP2D &pp ) const { 
00205         ParticleP2D res;
00206         res[0] = _x[0] - pp[0];
00207         res[1] = _x[1] - pp[1];
00208         res[2] = _x[2] - pp[2];
00209         res[3] = _x[3] - pp[3];
00210         res[4] = _x[4] - pp[4];
00211         return( res );
00212     }
00213 
00214     ParticleP2D operator*( double x ) const { 
00215         ParticleP2D res;
00216         res[0] = _x[0]*x;
00217         res[1] = _x[1]*x;
00218         res[2] = _x[2]*x;
00219         res[3] = _x[3]*x;
00220         res[4] = _x[4]*x;
00221         return( res );
00222     }
00223 
00226     void save( std::ostream &s ) const {
00227         write_double( s, _x[0] );
00228         write_double( s, _x[1] );
00229         write_double( s, _x[2] );
00230         write_double( s, _x[3] );
00231         write_double( s, _x[4] );
00232     }
00233     
00234     friend ParticleP2D operator*( double x, const ParticleP2D &pp );
00235 };
00236 
00237 
00238 inline std::ostream &operator<<( std::ostream &os, const ParticleP2D &pp )
00239 {
00240     os << "("
00241        << std::setw(12) << pp(0) << ", "
00242        << std::setw(12) << pp(1) << ", "
00243        << std::setw(12) << pp(2) << ", "
00244        << std::setw(12) << pp(3) << ", "
00245        << std::setw(12) << pp(4) << ")";
00246     return( os );
00247 }
00248 
00249 
00250 inline ParticleP2D operator*( double x, const ParticleP2D &pp )
00251 {
00252     ParticleP2D res;
00253     res[0] = pp[0]*x;
00254     res[1] = pp[1]*x;
00255     res[2] = pp[2]*x;
00256     res[3] = pp[3]*x;
00257     res[4] = pp[4]*x;
00258     return( res );
00259 }
00260 
00261 
00267 class ParticlePCyl : public ParticlePBase 
00268 {
00269     double         _x[6];   
00271 public:
00272 
00275     ParticlePCyl() {}
00276 
00279     ParticlePCyl( double t, double x, double vx, double r, double vr, double w ) {
00280         _x[0] = t; _x[1] = x; _x[2] = vx; _x[3] = r; _x[4] = vr; _x[5] = w;
00281     }
00282 
00285     ParticlePCyl( std::istream &s ) {
00286         _x[0] = read_double( s );
00287         _x[1] = read_double( s );
00288         _x[2] = read_double( s );
00289         _x[3] = read_double( s );
00290         _x[4] = read_double( s );
00291         _x[5] = read_double( s );
00292     }
00293 
00296     static geom_mode_e geom_mode() { return(MODE_CYL); }
00297 
00300     static size_t dim() { return(2); }
00301 
00304     static size_t size() { return(6); }
00305 
00322     static int get_derivatives( double t, const double *x, double *dxdt, void *data );
00323 
00328     static int trajectory_intersections_at_plane( std::vector<ParticlePCyl> &intsc, 
00329                                                   int crd, double val,
00330                                                   const ParticlePCyl &x1,
00331                                                   const ParticlePCyl &x2,
00332                                                   int extrapolate = 0 );
00333 
00338     static const std::string IQ_unit() { return( "A" ); }
00339 
00342     Vec3D location() const { return( Vec3D( _x[1], _x[3], 0.0 ) ); }
00343 
00346     Vec3D velocity() const { return( Vec3D( _x[2], _x[4], _x[5]*_x[3] ) ); }
00347 
00350     double speed() { return( sqrt(_x[2]*_x[2] + _x[4]*_x[4] + _x[3]*_x[3]*_x[5]*_x[5]) ); }
00351 
00354     double &operator[]( int i ) { return( _x[i] ); }
00355 
00358     const double &operator[]( int i ) const { return( _x[i] ); }
00359 
00362     double &operator()( int i ) { return( _x[i] ); }
00363 
00366     const double &operator()( int i ) const { return( _x[i] ); }
00367 
00368     ParticlePCyl operator+( const ParticlePCyl &pp ) const { 
00369         ParticlePCyl res;
00370         res[0] = _x[0] + pp[0];
00371         res[1] = _x[1] + pp[1];
00372         res[2] = _x[2] + pp[2];
00373         res[3] = _x[3] + pp[3];
00374         res[4] = _x[4] + pp[4];
00375         res[5] = _x[5] + pp[5];
00376         return( res );
00377     }
00378 
00379     ParticlePCyl operator-( const ParticlePCyl &pp ) const { 
00380         ParticlePCyl res;
00381         res[0] = _x[0] - pp[0];
00382         res[1] = _x[1] - pp[1];
00383         res[2] = _x[2] - pp[2];
00384         res[3] = _x[3] - pp[3];
00385         res[4] = _x[4] - pp[4];
00386         res[5] = _x[5] - pp[5];
00387         return( res );
00388     }
00389 
00390     ParticlePCyl operator*( double x ) const { 
00391         ParticlePCyl res;
00392         res[0] = _x[0]*x;
00393         res[1] = _x[1]*x;
00394         res[2] = _x[2]*x;
00395         res[3] = _x[3]*x;
00396         res[4] = _x[4]*x;
00397         res[5] = _x[5]*x;
00398         return( res );
00399     }
00400 
00403     void save( std::ostream &s ) const {
00404         write_double( s, _x[0] );
00405         write_double( s, _x[1] );
00406         write_double( s, _x[2] );
00407         write_double( s, _x[3] );
00408         write_double( s, _x[4] );
00409         write_double( s, _x[5] );
00410     }
00411     
00412     friend ParticlePCyl operator*( double x, const ParticlePCyl &pp );
00413 };
00414 
00415 
00416 inline std::ostream &operator<<( std::ostream &os, const ParticlePCyl &pp )
00417 {
00418     os << "("
00419        << std::setw(12) << pp(0) << ", "
00420        << std::setw(12) << pp(1) << ", "
00421        << std::setw(12) << pp(2) << ", "
00422        << std::setw(12) << pp(3) << ", "
00423        << std::setw(12) << pp(4) << ", "
00424        << std::setw(12) << pp(5) << ")";
00425     return( os );
00426 }
00427 
00428 
00429 inline ParticlePCyl operator*( double x, const ParticlePCyl &pp )
00430 {
00431     ParticlePCyl res;
00432     res[0] = pp[0]*x;
00433     res[1] = pp[1]*x;
00434     res[2] = pp[2]*x;
00435     res[3] = pp[3]*x;
00436     res[4] = pp[4]*x;
00437     res[5] = pp[5]*x;
00438     return( res );
00439 }
00440 
00441 
00447 class ParticleP3D : public ParticlePBase 
00448 {
00449     double         _x[7];   
00451 public:
00452 
00455     ParticleP3D() {}
00456 
00459     ParticleP3D( double t, double x, double vx, double y, double vy, double z, double vz ) {
00460         _x[0] = t; _x[1] = x; _x[2] = vx; _x[3] = y; _x[4] = vy; _x[5] = z; _x[6] = vz;
00461     }
00462 
00465     ParticleP3D( std::istream &s ) {
00466         _x[0] = read_double( s );
00467         _x[1] = read_double( s );
00468         _x[2] = read_double( s );
00469         _x[3] = read_double( s );
00470         _x[4] = read_double( s );
00471         _x[5] = read_double( s );
00472         _x[6] = read_double( s );
00473     }
00474 
00477     static geom_mode_e geom_mode() { return(MODE_3D); }
00478 
00481     static size_t dim() { return(3); }
00482 
00485     static size_t size() { return(7); }
00486 
00500     static int get_derivatives( double t, const double *x, double *dxdt, void *data );
00501 
00506     static int trajectory_intersections_at_plane( std::vector<ParticleP3D> &intsc, 
00507                                                   int crd, double val,
00508                                                   const ParticleP3D &x1, 
00509                                                   const ParticleP3D &x2, 
00510                                                   int extrapolate = 0 );
00511 
00516     static const std::string IQ_unit() { return( "A" ); }
00517 
00520     Vec3D location() const { return( Vec3D( _x[1], _x[3], _x[5] ) ); }
00521 
00524     Vec3D velocity() const { return( Vec3D( _x[2], _x[4], _x[6] ) ); }
00525 
00528     double speed() { return( sqrt(_x[2]*_x[2] + _x[4]*_x[4] + _x[6]*_x[6]) ); }
00529 
00532     double &operator[]( int i ) { return( _x[i] ); }
00533 
00536     const double &operator[]( int i ) const { return( _x[i] ); }
00537 
00540     double &operator()( int i ) { return( _x[i] ); }
00541 
00544     const double &operator()( int i ) const { return( _x[i] ); }
00545 
00546     ParticleP3D operator+( const ParticleP3D &pp ) const { 
00547         ParticleP3D res;
00548         res[0] = _x[0] + pp[0];
00549         res[1] = _x[1] + pp[1];
00550         res[2] = _x[2] + pp[2];
00551         res[3] = _x[3] + pp[3];
00552         res[4] = _x[4] + pp[4];
00553         res[5] = _x[5] + pp[5];
00554         res[6] = _x[6] + pp[6];
00555         return( res );
00556     }
00557 
00558     ParticleP3D operator-( const ParticleP3D &pp ) const { 
00559         ParticleP3D res;
00560         res[0] = _x[0] - pp[0];
00561         res[1] = _x[1] - pp[1];
00562         res[2] = _x[2] - pp[2];
00563         res[3] = _x[3] - pp[3];
00564         res[4] = _x[4] - pp[4];
00565         res[5] = _x[5] - pp[5];
00566         res[6] = _x[6] - pp[6];
00567         return( res );
00568     }
00569 
00570     ParticleP3D operator*( double x ) const { 
00571         ParticleP3D res;
00572         res[0] = _x[0]*x;
00573         res[1] = _x[1]*x;
00574         res[2] = _x[2]*x;
00575         res[3] = _x[3]*x;
00576         res[4] = _x[4]*x;
00577         res[5] = _x[5]*x;
00578         res[6] = _x[6]*x;
00579         return( res );
00580     }
00581 
00584     void save( std::ostream &s ) const {
00585         write_double( s, _x[0] );
00586         write_double( s, _x[1] );
00587         write_double( s, _x[2] );
00588         write_double( s, _x[3] );
00589         write_double( s, _x[4] );
00590         write_double( s, _x[5] );
00591         write_double( s, _x[6] );
00592     }
00593     
00594     friend ParticleP3D operator*( double x, const ParticleP3D &pp );
00595 };
00596 
00597 
00598 inline std::ostream &operator<<( std::ostream &os, const ParticleP3D &pp )
00599 {
00600     os << "("
00601        << std::setw(12) << pp(0) << ", "
00602        << std::setw(12) << pp(1) << ", "
00603        << std::setw(12) << pp(2) << ", "
00604        << std::setw(12) << pp(3) << ", "
00605        << std::setw(12) << pp(4) << ", "
00606        << std::setw(12) << pp(5) << ", "
00607        << std::setw(12) << pp(6) << ")";
00608     return( os );
00609 }
00610 
00611 
00612 inline ParticleP3D operator*( double x, const ParticleP3D &pp )
00613 {
00614     ParticleP3D res;
00615     res[0] = pp[0]*x;
00616     res[1] = pp[1]*x;
00617     res[2] = pp[2]*x;
00618     res[3] = pp[3]*x;
00619     res[4] = pp[4]*x;
00620     res[5] = pp[5]*x;
00621     res[6] = pp[6]*x;
00622     return( res );
00623 }
00624 
00625 
00626 
00627 
00628 /* ************************************************************************************** *
00629  * Particle classes                                                                       *
00630  * ************************************************************************************** */
00631 
00632 
00637 class ParticleBase
00638 {
00639 protected:
00640 
00641     particle_status_e   _status;       
00642     double              _IQ;           
00653     double              _q;            
00654     double              _m;            
00656     ParticleBase( double IQ, double q, double m ) 
00657         : _status(PARTICLE_OK), _q(q) {
00658         _m = fabs(m);
00659         if( _q < 0 )
00660             _IQ = -fabs(IQ);
00661         else
00662             _IQ = fabs(IQ);
00663     }
00664 
00667     ParticleBase( std::istream &s ) {
00668         _status = (particle_status_e)read_int32( s );
00669         _IQ = read_double( s );
00670         _q = read_double( s );
00671         _m = read_double( s );  
00672     }
00673 
00674     ~ParticleBase() {}
00675 
00676 public:
00677 
00680     particle_status_e get_status() { return( _status ); }
00681 
00684     void set_status( particle_status_e status ) { _status = status; }
00685 
00691     double IQ() const { return( _IQ ); }
00692 
00695     double q() const { return( _q ); }
00696 
00699     double m() const { return( _m ); }
00700 
00703     double qm() const { return( _q/_m ); }
00704 
00707     void save( std::ostream &s ) const {
00708         write_int32( s, _status );
00709         write_double( s, _IQ );
00710         write_double( s, _q );
00711         write_double( s, _m );
00712     }
00713 };
00714 
00715 
00724 template<class PP> class Particle : public ParticleBase
00725 {
00726     std::vector<PP>     _trajectory;   
00727     PP                  _x;            
00729 public:
00730 
00739     Particle( double IQ, double q, double m, const PP &x ) 
00740         : ParticleBase(IQ,q,m), _x(x) {}
00741 
00744     Particle( std::istream &s ) 
00745         : ParticleBase( s ) {
00746 
00747         uint32_t N  = read_int32( s );
00748         _trajectory.reserve( N );
00749         for( uint32_t a = 0; a < N; a++ )
00750             _trajectory.push_back( PP( s ) );
00751         _x = PP( s );
00752     }
00753 
00756     ~Particle() {}
00757 
00760     double &operator()( int i ) { return( _x(i) ); }
00761 
00764     const double &operator()( int i ) const { return( _x(i) ); }
00765 
00768     double &operator[]( int i ) { return( _x(i) ); }
00769 
00772     const double &operator[]( int i ) const { return( _x(i) ); }
00773 
00776     Vec3D location() const { return( _x.location() ); }
00777 
00780     Vec3D velocity() const { return( _x.velocity() ); }
00781 
00784     PP &x() { return( _x ); }
00785 
00788     const PP &x() const { return( _x ); }
00789 
00792     PP &traj( int i ) { return( _trajectory[i] ); }
00793 
00796     const PP &traj( int i ) const { return( _trajectory[i] ); }
00797 
00800     size_t traj_size( void ) const { return( _trajectory.size() ); }
00801 
00804     void add_trajectory_point( const PP &x ) { _trajectory.push_back( x ); }
00805 
00808     void copy_trajectory( const std::vector<PP> &traj ) { _trajectory = traj; }
00809 
00812     void clear_trajectory( void ) { _trajectory.clear(); }
00813 
00816     void save( std::ostream &s ) const {
00817         ParticleBase::save( s );
00818         write_int32( s, _trajectory.size() );
00819         for( uint32_t a = 0; a < _trajectory.size(); a++ )
00820             _trajectory[a].save( s );
00821         _x.save( s );
00822     }
00823     
00826     void debug_print( std::ostream &os ) const {
00827         size_t a;
00828         os << "**Particle\n";
00829         switch( _status ) {
00830         case PARTICLE_OK:
00831             os << "stat = PARTICLE_OK\n";
00832             break;
00833         case PARTICLE_OUT:
00834             os << "stat = PARTICLE_OUT\n";
00835             break;
00836         case PARTICLE_COLL:
00837             os << "stat = PARTICLE_COLL\n";
00838             break;
00839         case PARTICLE_BADDEF:
00840             os << "stat = PARTICLE_BADDEF\n";
00841             break;
00842         case PARTICLE_TIME:
00843             os << "stat = PARTICLE_TIME\n";
00844             break;
00845         case PARTICLE_NSTP:
00846             os << "stat = PARTICLE_NSTP\n";
00847             break;
00848         }
00849         os << "IQ   = " << _IQ << "\n";
00850         os << "q    = " << _q << "\n";
00851         os << "m    = " << _m << "\n";
00852         os << "x    = " << _x << "\n";
00853         os << "Trajectory:\n";
00854         for( a = 0; a < _trajectory.size(); a++ )
00855             os << "x[" << a << "] = " << _trajectory[a] << "\n";
00856 
00857         /*
00858         std::cout << "Trajectory:\n";
00859         for( a = 0; a < _trajectory.size(); a++ ) {
00860             std::cout << "x[" << a << "] = (";
00861             uint32_t b;
00862             const PP &tp = _trajectory[a];
00863             if( tp.size() > 0 ) {
00864                 for( b = 0; b < tp.size()-1; b++ )
00865                     std::cout << tp[b] << ", ";
00866                 std::cout << tp[b] << ")\n";
00867             } else {
00868                 std::cout << ")\n";
00869             }
00870         }
00871         */
00872     }
00873 };
00874 
00875 
00880 typedef Particle<ParticleP2D>  Particle2D;
00881 
00882 
00887 typedef Particle<ParticlePCyl> ParticleCyl;
00888 
00889 
00894 typedef Particle<ParticleP3D>  Particle3D;
00895 
00896 
00897 
00900 struct ParticleIteratorData {
00901     ScalarField              *_scharge;  
00902     const VectorField        *_efield;   
00903     const VectorField        *_bfield;   
00904     const Geometry           *_geom;     
00905     double                    _qm;       
00906     const CallbackFunctorD_V *_bsup_cb;  
00908     ParticleIteratorData( ScalarField *scharge, const VectorField *efield, 
00909                           const VectorField *bfield, const Geometry *geom ) 
00910         : _scharge(scharge), _efield(efield), _bfield(bfield), 
00911           _geom(geom), _qm(0.0), _bsup_cb(0) {}
00912 
00915     void set_bfield_suppression_callback( const CallbackFunctorD_V *bsup_cb ) {
00916         _bsup_cb = bsup_cb;
00917     }
00918 
00919 };
00920 
00921 
00922 
00923 #endif


Reference manual for Ion Beam Simulator 1.0.4dev
Generated by Doxygen 1.7.1 on Wed May 18 2011 23:03:48.