Navigation

Main Page
Download
Support
Installation
Tutorial
Examples
Reference Manual
   Version 1.0.5new_solver
   Version 1.0.5dev
      Class Index
      File List
   Version 1.0.5b
   Version 1.0.4dev
   Version 1.0.4
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 differ from internal GSL
00058  * error values */
00059 #define IBSIMU_DERIV_ERROR 201
00060 
00061 
00069 enum particle_status_e {
00070     PARTICLE_OK = 0,
00071     PARTICLE_OUT,
00072     PARTICLE_COLL,
00073     PARTICLE_BADDEF,
00074     PARTICLE_TIME,
00075     PARTICLE_NSTP 
00076 };
00077 
00078 
00079 
00080 /* ************************************************************************************* *
00081  * Particle point classes                                                                *
00082  * ************************************************************************************* */
00083 
00084 
00089 class ParticlePBase
00090 {
00091 
00092 };
00093 
00094 
00100 class ParticleP2D : public ParticlePBase 
00101 {
00102     double         _x[5];   
00104 public:
00105 
00108     ParticleP2D() {}
00109 
00112     ParticleP2D( double t, double x, double vx, double y, double vy ) {
00113         _x[0] = t; _x[1] = x; _x[2] = vx; _x[3] = y; _x[4] = vy;
00114     }
00115 
00118     ParticleP2D( std::istream &s ) {
00119         _x[0] = read_double( s );
00120         _x[1] = read_double( s );
00121         _x[2] = read_double( s );
00122         _x[3] = read_double( s );
00123         _x[4] = read_double( s );
00124     }
00125 
00128     static geom_mode_e geom_mode() { return(MODE_2D); }
00129 
00132     static size_t dim() { return(2); }
00133 
00136     static size_t size() { return(5); }
00137 
00149     static int get_derivatives( double t, const double *x, double *dxdt, void *data );
00150 
00155     static int trajectory_intersections_at_plane( std::vector<ParticleP2D> &intsc, 
00156                                                   int crd, double val,
00157                                                   const ParticleP2D &x1, 
00158                                                   const ParticleP2D &x2,
00159                                                   int extrapolate = 0 );
00160 
00165     static const std::string IQ_unit() { return( "A/m" ); }
00166 
00169     Vec3D location() const { return( Vec3D( _x[1], _x[3], 0.0 ) ); }
00170 
00173     Vec3D velocity() const { return( Vec3D( _x[2], _x[4], 0.0 ) ); }
00174 
00177     double speed() { return( sqrt(_x[2]*_x[2] + _x[4]*_x[4]) ); }
00178 
00181     double &operator[]( int i ) { return( _x[i] ); }
00182 
00185     const double &operator[]( int i ) const { return( _x[i] ); }
00186 
00189     double &operator()( int i ) { return( _x[i] ); }
00190 
00193     const double &operator()( int i ) const { return( _x[i] ); }
00194 
00195     ParticleP2D operator+( const ParticleP2D &pp ) const { 
00196         ParticleP2D res;
00197         res[0] = _x[0] + pp[0];
00198         res[1] = _x[1] + pp[1];
00199         res[2] = _x[2] + pp[2];
00200         res[3] = _x[3] + pp[3];
00201         res[4] = _x[4] + pp[4];
00202         return( res );
00203     }
00204 
00205     ParticleP2D operator-( const ParticleP2D &pp ) const { 
00206         ParticleP2D res;
00207         res[0] = _x[0] - pp[0];
00208         res[1] = _x[1] - pp[1];
00209         res[2] = _x[2] - pp[2];
00210         res[3] = _x[3] - pp[3];
00211         res[4] = _x[4] - pp[4];
00212         return( res );
00213     }
00214 
00215     ParticleP2D operator*( double x ) const { 
00216         ParticleP2D res;
00217         res[0] = _x[0]*x;
00218         res[1] = _x[1]*x;
00219         res[2] = _x[2]*x;
00220         res[3] = _x[3]*x;
00221         res[4] = _x[4]*x;
00222         return( res );
00223     }
00224 
00227     void save( std::ostream &s ) const {
00228         write_double( s, _x[0] );
00229         write_double( s, _x[1] );
00230         write_double( s, _x[2] );
00231         write_double( s, _x[3] );
00232         write_double( s, _x[4] );
00233     }
00234     
00235     friend ParticleP2D operator*( double x, const ParticleP2D &pp );
00236 };
00237 
00238 
00239 inline std::ostream &operator<<( std::ostream &os, const ParticleP2D &pp )
00240 {
00241     os << "("
00242        << std::setw(12) << pp(0) << ", "
00243        << std::setw(12) << pp(1) << ", "
00244        << std::setw(12) << pp(2) << ", "
00245        << std::setw(12) << pp(3) << ", "
00246        << std::setw(12) << pp(4) << ")";
00247     return( os );
00248 }
00249 
00250 
00251 inline ParticleP2D operator*( double x, const ParticleP2D &pp )
00252 {
00253     ParticleP2D res;
00254     res[0] = pp[0]*x;
00255     res[1] = pp[1]*x;
00256     res[2] = pp[2]*x;
00257     res[3] = pp[3]*x;
00258     res[4] = pp[4]*x;
00259     return( res );
00260 }
00261 
00262 
00268 class ParticlePCyl : public ParticlePBase 
00269 {
00270     double         _x[6];   
00272 public:
00273 
00276     ParticlePCyl() {}
00277 
00280     ParticlePCyl( double t, double x, double vx, double r, double vr, double w ) {
00281         _x[0] = t; _x[1] = x; _x[2] = vx; _x[3] = r; _x[4] = vr; _x[5] = w;
00282     }
00283 
00286     ParticlePCyl( std::istream &s ) {
00287         _x[0] = read_double( s );
00288         _x[1] = read_double( s );
00289         _x[2] = read_double( s );
00290         _x[3] = read_double( s );
00291         _x[4] = read_double( s );
00292         _x[5] = read_double( s );
00293     }
00294 
00297     static geom_mode_e geom_mode() { return(MODE_CYL); }
00298 
00301     static size_t dim() { return(2); }
00302 
00305     static size_t size() { return(6); }
00306 
00323     static int get_derivatives( double t, const double *x, double *dxdt, void *data );
00324 
00329     static int trajectory_intersections_at_plane( std::vector<ParticlePCyl> &intsc, 
00330                                                   int crd, double val,
00331                                                   const ParticlePCyl &x1,
00332                                                   const ParticlePCyl &x2,
00333                                                   int extrapolate = 0 );
00334 
00339     static const std::string IQ_unit() { return( "A" ); }
00340 
00343     Vec3D location() const { return( Vec3D( _x[1], _x[3], 0.0 ) ); }
00344 
00347     Vec3D velocity() const { return( Vec3D( _x[2], _x[4], _x[5]*_x[3] ) ); }
00348 
00351     double speed() { return( sqrt(_x[2]*_x[2] + _x[4]*_x[4] + _x[3]*_x[3]*_x[5]*_x[5]) ); }
00352 
00355     double &operator[]( int i ) { return( _x[i] ); }
00356 
00359     const double &operator[]( int i ) const { return( _x[i] ); }
00360 
00363     double &operator()( int i ) { return( _x[i] ); }
00364 
00367     const double &operator()( int i ) const { return( _x[i] ); }
00368 
00369     ParticlePCyl operator+( const ParticlePCyl &pp ) const { 
00370         ParticlePCyl res;
00371         res[0] = _x[0] + pp[0];
00372         res[1] = _x[1] + pp[1];
00373         res[2] = _x[2] + pp[2];
00374         res[3] = _x[3] + pp[3];
00375         res[4] = _x[4] + pp[4];
00376         res[5] = _x[5] + pp[5];
00377         return( res );
00378     }
00379 
00380     ParticlePCyl operator-( const ParticlePCyl &pp ) const { 
00381         ParticlePCyl res;
00382         res[0] = _x[0] - pp[0];
00383         res[1] = _x[1] - pp[1];
00384         res[2] = _x[2] - pp[2];
00385         res[3] = _x[3] - pp[3];
00386         res[4] = _x[4] - pp[4];
00387         res[5] = _x[5] - pp[5];
00388         return( res );
00389     }
00390 
00391     ParticlePCyl operator*( double x ) const { 
00392         ParticlePCyl res;
00393         res[0] = _x[0]*x;
00394         res[1] = _x[1]*x;
00395         res[2] = _x[2]*x;
00396         res[3] = _x[3]*x;
00397         res[4] = _x[4]*x;
00398         res[5] = _x[5]*x;
00399         return( res );
00400     }
00401 
00404     void save( std::ostream &s ) const {
00405         write_double( s, _x[0] );
00406         write_double( s, _x[1] );
00407         write_double( s, _x[2] );
00408         write_double( s, _x[3] );
00409         write_double( s, _x[4] );
00410         write_double( s, _x[5] );
00411     }
00412     
00413     friend ParticlePCyl operator*( double x, const ParticlePCyl &pp );
00414 };
00415 
00416 
00417 inline std::ostream &operator<<( std::ostream &os, const ParticlePCyl &pp )
00418 {
00419     os << "("
00420        << std::setw(12) << pp(0) << ", "
00421        << std::setw(12) << pp(1) << ", "
00422        << std::setw(12) << pp(2) << ", "
00423        << std::setw(12) << pp(3) << ", "
00424        << std::setw(12) << pp(4) << ", "
00425        << std::setw(12) << pp(5) << ")";
00426     return( os );
00427 }
00428 
00429 
00430 inline ParticlePCyl operator*( double x, const ParticlePCyl &pp )
00431 {
00432     ParticlePCyl res;
00433     res[0] = pp[0]*x;
00434     res[1] = pp[1]*x;
00435     res[2] = pp[2]*x;
00436     res[3] = pp[3]*x;
00437     res[4] = pp[4]*x;
00438     res[5] = pp[5]*x;
00439     return( res );
00440 }
00441 
00442 
00448 class ParticleP3D : public ParticlePBase 
00449 {
00450     double         _x[7];   
00452 public:
00453 
00456     ParticleP3D() {}
00457 
00460     ParticleP3D( double t, double x, double vx, double y, double vy, double z, double vz ) {
00461         _x[0] = t; _x[1] = x; _x[2] = vx; _x[3] = y; _x[4] = vy; _x[5] = z; _x[6] = vz;
00462     }
00463 
00466     ParticleP3D( std::istream &s ) {
00467         _x[0] = read_double( s );
00468         _x[1] = read_double( s );
00469         _x[2] = read_double( s );
00470         _x[3] = read_double( s );
00471         _x[4] = read_double( s );
00472         _x[5] = read_double( s );
00473         _x[6] = read_double( s );
00474     }
00475 
00478     static geom_mode_e geom_mode() { return(MODE_3D); }
00479 
00482     static size_t dim() { return(3); }
00483 
00486     static size_t size() { return(7); }
00487 
00501     static int get_derivatives( double t, const double *x, double *dxdt, void *data );
00502 
00507     static int trajectory_intersections_at_plane( std::vector<ParticleP3D> &intsc, 
00508                                                   int crd, double val,
00509                                                   const ParticleP3D &x1, 
00510                                                   const ParticleP3D &x2, 
00511                                                   int extrapolate = 0 );
00512 
00517     static const std::string IQ_unit() { return( "A" ); }
00518 
00521     Vec3D location() const { return( Vec3D( _x[1], _x[3], _x[5] ) ); }
00522 
00525     Vec3D velocity() const { return( Vec3D( _x[2], _x[4], _x[6] ) ); }
00526 
00529     double speed() { return( sqrt(_x[2]*_x[2] + _x[4]*_x[4] + _x[6]*_x[6]) ); }
00530 
00533     double &operator[]( int i ) { return( _x[i] ); }
00534 
00537     const double &operator[]( int i ) const { return( _x[i] ); }
00538 
00541     double &operator()( int i ) { return( _x[i] ); }
00542 
00545     const double &operator()( int i ) const { return( _x[i] ); }
00546 
00547     ParticleP3D operator+( const ParticleP3D &pp ) const { 
00548         ParticleP3D res;
00549         res[0] = _x[0] + pp[0];
00550         res[1] = _x[1] + pp[1];
00551         res[2] = _x[2] + pp[2];
00552         res[3] = _x[3] + pp[3];
00553         res[4] = _x[4] + pp[4];
00554         res[5] = _x[5] + pp[5];
00555         res[6] = _x[6] + pp[6];
00556         return( res );
00557     }
00558 
00559     ParticleP3D operator-( const ParticleP3D &pp ) const { 
00560         ParticleP3D res;
00561         res[0] = _x[0] - pp[0];
00562         res[1] = _x[1] - pp[1];
00563         res[2] = _x[2] - pp[2];
00564         res[3] = _x[3] - pp[3];
00565         res[4] = _x[4] - pp[4];
00566         res[5] = _x[5] - pp[5];
00567         res[6] = _x[6] - pp[6];
00568         return( res );
00569     }
00570 
00571     ParticleP3D operator*( double x ) const { 
00572         ParticleP3D res;
00573         res[0] = _x[0]*x;
00574         res[1] = _x[1]*x;
00575         res[2] = _x[2]*x;
00576         res[3] = _x[3]*x;
00577         res[4] = _x[4]*x;
00578         res[5] = _x[5]*x;
00579         res[6] = _x[6]*x;
00580         return( res );
00581     }
00582 
00585     void save( std::ostream &s ) const {
00586         write_double( s, _x[0] );
00587         write_double( s, _x[1] );
00588         write_double( s, _x[2] );
00589         write_double( s, _x[3] );
00590         write_double( s, _x[4] );
00591         write_double( s, _x[5] );
00592         write_double( s, _x[6] );
00593     }
00594     
00595     friend ParticleP3D operator*( double x, const ParticleP3D &pp );
00596 };
00597 
00598 
00599 inline std::ostream &operator<<( std::ostream &os, const ParticleP3D &pp )
00600 {
00601     os << "("
00602        << std::setw(12) << pp(0) << ", "
00603        << std::setw(12) << pp(1) << ", "
00604        << std::setw(12) << pp(2) << ", "
00605        << std::setw(12) << pp(3) << ", "
00606        << std::setw(12) << pp(4) << ", "
00607        << std::setw(12) << pp(5) << ", "
00608        << std::setw(12) << pp(6) << ")";
00609     return( os );
00610 }
00611 
00612 
00613 inline ParticleP3D operator*( double x, const ParticleP3D &pp )
00614 {
00615     ParticleP3D res;
00616     res[0] = pp[0]*x;
00617     res[1] = pp[1]*x;
00618     res[2] = pp[2]*x;
00619     res[3] = pp[3]*x;
00620     res[4] = pp[4]*x;
00621     res[5] = pp[5]*x;
00622     res[6] = pp[6]*x;
00623     return( res );
00624 }
00625 
00626 
00627 
00628 
00629 /* ************************************************************************************** *
00630  * Particle classes                                                                       *
00631  * ************************************************************************************** */
00632 
00633 
00638 class ParticleBase
00639 {
00640 protected:
00641 
00642     particle_status_e   _status;       
00643     double              _IQ;           
00654     double              _q;            
00655     double              _m;            
00657     ParticleBase( double IQ, double q, double m ) 
00658         : _status(PARTICLE_OK), _q(q) {
00659         _m = fabs(m);
00660         if( _q < 0 )
00661             _IQ = -fabs(IQ);
00662         else
00663             _IQ = fabs(IQ);
00664     }
00665 
00668     ParticleBase( std::istream &s ) {
00669         _status = (particle_status_e)read_int32( s );
00670         _IQ = read_double( s );
00671         _q = read_double( s );
00672         _m = read_double( s );  
00673     }
00674 
00675     ~ParticleBase() {}
00676 
00677 public:
00678 
00681     particle_status_e get_status() { return( _status ); }
00682 
00685     void set_status( particle_status_e status ) { _status = status; }
00686 
00692     double IQ() const { return( _IQ ); }
00693 
00696     double q() const { return( _q ); }
00697 
00700     double m() const { return( _m ); }
00701 
00704     double qm() const { return( _q/_m ); }
00705 
00708     void save( std::ostream &s ) const {
00709         write_int32( s, _status );
00710         write_double( s, _IQ );
00711         write_double( s, _q );
00712         write_double( s, _m );
00713     }
00714 };
00715 
00716 
00725 template<class PP> class Particle : public ParticleBase
00726 {
00727     std::vector<PP>     _trajectory;   
00728     PP                  _x;            
00730 public:
00731 
00740     Particle( double IQ, double q, double m, const PP &x ) 
00741         : ParticleBase(IQ,q,m), _x(x) {}
00742 
00745     Particle( std::istream &s ) 
00746         : ParticleBase( s ) {
00747 
00748         uint32_t N  = read_int32( s );
00749         _trajectory.reserve( N );
00750         for( uint32_t a = 0; a < N; a++ )
00751             _trajectory.push_back( PP( s ) );
00752         _x = PP( s );
00753     }
00754 
00757     ~Particle() {}
00758 
00761     double &operator()( int i ) { return( _x(i) ); }
00762 
00765     const double &operator()( int i ) const { return( _x(i) ); }
00766 
00769     double &operator[]( int i ) { return( _x(i) ); }
00770 
00773     const double &operator[]( int i ) const { return( _x(i) ); }
00774 
00777     Vec3D location() const { return( _x.location() ); }
00778 
00781     Vec3D velocity() const { return( _x.velocity() ); }
00782 
00785     PP &x() { return( _x ); }
00786 
00789     const PP &x() const { return( _x ); }
00790 
00793     PP &traj( int i ) { return( _trajectory[i] ); }
00794 
00797     const PP &traj( int i ) const { return( _trajectory[i] ); }
00798 
00801     size_t traj_size( void ) const { return( _trajectory.size() ); }
00802 
00805     void add_trajectory_point( const PP &x ) { _trajectory.push_back( x ); }
00806 
00809     void copy_trajectory( const std::vector<PP> &traj ) { _trajectory = traj; }
00810 
00813     void clear_trajectory( void ) { _trajectory.clear(); }
00814 
00817     void save( std::ostream &s ) const {
00818         ParticleBase::save( s );
00819         write_int32( s, _trajectory.size() );
00820         for( uint32_t a = 0; a < _trajectory.size(); a++ )
00821             _trajectory[a].save( s );
00822         _x.save( s );
00823     }
00824     
00827     void debug_print( std::ostream &os ) const {
00828         size_t a;
00829         os << "**Particle\n";
00830         switch( _status ) {
00831         case PARTICLE_OK:
00832             os << "stat = PARTICLE_OK\n";
00833             break;
00834         case PARTICLE_OUT:
00835             os << "stat = PARTICLE_OUT\n";
00836             break;
00837         case PARTICLE_COLL:
00838             os << "stat = PARTICLE_COLL\n";
00839             break;
00840         case PARTICLE_BADDEF:
00841             os << "stat = PARTICLE_BADDEF\n";
00842             break;
00843         case PARTICLE_TIME:
00844             os << "stat = PARTICLE_TIME\n";
00845             break;
00846         case PARTICLE_NSTP:
00847             os << "stat = PARTICLE_NSTP\n";
00848             break;
00849         }
00850         os << "IQ   = " << _IQ << "\n";
00851         os << "q    = " << _q << "\n";
00852         os << "m    = " << _m << "\n";
00853         os << "x    = " << _x << "\n";
00854         os << "Trajectory:\n";
00855         for( a = 0; a < _trajectory.size(); a++ )
00856             os << "x[" << a << "] = " << _trajectory[a] << "\n";
00857 
00858         /*
00859         std::cout << "Trajectory:\n";
00860         for( a = 0; a < _trajectory.size(); a++ ) {
00861             std::cout << "x[" << a << "] = (";
00862             uint32_t b;
00863             const PP &tp = _trajectory[a];
00864             if( tp.size() > 0 ) {
00865                 for( b = 0; b < tp.size()-1; b++ )
00866                     std::cout << tp[b] << ", ";
00867                 std::cout << tp[b] << ")\n";
00868             } else {
00869                 std::cout << ")\n";
00870             }
00871         }
00872         */
00873     }
00874 };
00875 
00876 
00881 typedef Particle<ParticleP2D>  Particle2D;
00882 
00883 
00888 typedef Particle<ParticlePCyl> ParticleCyl;
00889 
00890 
00895 typedef Particle<ParticleP3D>  Particle3D;
00896 
00897 
00898 
00901 struct ParticleIteratorData {
00902     ScalarField              *_scharge;      
00903     const VectorField        *_efield;       
00904     const VectorField        *_bfield;       
00905     const Geometry           *_geom;         
00907     double                    _qm;           
00908     const CallbackFunctorD_V *_bsup_cb;      
00909     bool                      _relativistic; 
00911     ParticleIteratorData( ScalarField *scharge, const VectorField *efield, 
00912                           const VectorField *bfield, const Geometry *geom ) 
00913         : _scharge(scharge), _efield(efield), _bfield(bfield), 
00914           _geom(geom), _qm(0.0), _bsup_cb(0), _relativistic(false) {}
00915 
00918     void set_bfield_suppression_callback( const CallbackFunctorD_V *bsup_cb ) {
00919         _bsup_cb = bsup_cb;
00920     }
00921 
00924     void set_relativistic( bool enable ) {
00925         _relativistic = enable;
00926     }
00927 
00928 };
00929 
00930 
00931 
00932 #endif
00933 


Reference manual for Ion Beam Simulator 1.0.5dev
Generated by Doxygen 1.7.1 on Mon Feb 6 2012 15:07:16.