Navigation

Main Page
Download
Support
Installation
Tutorial
Examples
Reference Manual
   Version 1.0.5new_solver
      Class Index
      File List
   Version 1.0.5dev
   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
particledatabaseimp.hpp
Go to the documentation of this file.
1 
5 /* Copyright (c) 2005-2013 Taneli Kalvas. All rights reserved.
6  *
7  * You can redistribute this software and/or modify it under the terms
8  * of the GNU General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This library is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this library (file "COPYING" included in the package);
19  * if not, write to the Free Software Foundation, Inc., 51 Franklin
20  * Street, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  * If you have questions about your rights to use or distribute this
23  * software, please contact Berkeley Lab's Technology Transfer
24  * Department at TTD@lbl.gov. Other questions, comments and bug
25  * reports should be sent directly to the author via email at
26  * taneli.kalvas@jyu.fi.
27  *
28  * NOTICE. This software was developed under partial funding from the
29  * U.S. Department of Energy. As such, the U.S. Government has been
30  * granted for itself and others acting on its behalf a paid-up,
31  * nonexclusive, irrevocable, worldwide license in the Software to
32  * reproduce, prepare derivative works, and perform publicly and
33  * display publicly. Beginning five (5) years after the date
34  * permission to assert copyright is obtained from the U.S. Department
35  * of Energy, and subject to any subsequent five (5) year renewals,
36  * the U.S. Government is granted for itself and others acting on its
37  * behalf a paid-up, nonexclusive, irrevocable, worldwide license in
38  * the Software to reproduce, prepare derivative works, distribute
39  * copies to the public, perform publicly and display publicly, and to
40  * permit others to do so.
41  */
42 
43 #ifndef PARTICLEDATABASEIMP_HPP
44 #define PARTICLEDATABASEIMP_HPP 1
45 
46 
47 #include "ibsimu.hpp"
48 #include "statusprint.hpp"
49 #include "timer.hpp"
50 #include "file.hpp"
51 #include "particles.hpp"
52 #include "particleiterator.hpp"
54 
55 
57 
58 protected:
59 
60  const Geometry &_geom;
61  double _epsabs;
62  double _epsrel;
65  uint32_t _maxsteps;
66  double _maxt;
67  bool _save_points;
68  uint32_t _trajdiv;
70  bool _mirror[6];
72  double _rhosum;
76  uint32_t _iteration;
86  ParticleDataBaseImp( ParticleDataBase *pdb, const Geometry &geom );
87 
88  ParticleDataBaseImp( ParticleDataBase *pdb, std::istream &s, const Geometry &geom );
89 
91 
92  const ParticleDataBaseImp &operator=( const ParticleDataBaseImp &pdb );
93 
98  static double energy_to_velocity( double E, double m );
99 
100  void save( std::ostream &os ) const;
101 
102 public:
103 
104  virtual ~ParticleDataBaseImp();
105 
106  void set_accuracy( double epsabs, double epsrel );
107 
108  void set_bfield_suppression( const CallbackFunctorD_V *functor );
109 
110  void set_trajectory_handler_callback( TrajectoryHandlerCallback *thand_cb );
111 
112  void set_trajectory_end_callback( TrajectoryEndCallback *tend_cb );
113 
114  void set_trajectory_surface_collision_callback( TrajectorySurfaceCollisionCallback *tsur_cb );
115 
116  void set_relativistic( bool enable );
117 
118  void set_surface_collision( bool surface_collision );
119 
120  void set_polyint( bool polyint );
121 
122  bool get_polyint( void ) const;
123 
124  void set_trajectory_interpolation( trajectory_interpolation_e intrp );
125 
126  trajectory_interpolation_e get_trajectory_interpolation( void ) const;
127 
128  void set_scharge_deposition( scharge_deposition_e type );
129 
130  scharge_deposition_e get_scharge_deposition( void ) const;
131 
132  void set_max_steps( uint32_t maxsteps );
133 
134  void set_max_time( double maxt );
135 
136  void set_save_all_points( bool save_points );
137 
138  void set_save_trajectories( uint32_t div );
139 
140  uint32_t get_save_trajectories( void ) const;
141 
142  void set_mirror( const bool mirror[6] );
143 
144  void get_mirror( bool mirror[6] ) const;
145 
146  int get_iteration_number( void ) const;
147 
148  double get_rhosum( void ) const;
149 
150  void set_rhosum( double rhosum );
151 
152  const ParticleStatistics &get_statistics( void ) const;
153 
154  virtual geom_mode_e geom_mode() const = 0;
155 
156  virtual size_t size( void ) const = 0;
157 
158  virtual size_t traj_size( uint32_t i ) const = 0;
159 
160  virtual double traj_length( uint32_t i ) const = 0;
161 
162  virtual void trajectory_point( double &t, Vec3D &loc, Vec3D &vel, uint32_t i, uint32_t j ) const = 0;
163 
164  virtual void trajectories_at_plane( TrajectoryDiagnosticData &tdata,
165  coordinate_axis_e axis,
166  double val,
167  const std::vector<trajectory_diagnostic_e> &diagnostics ) const = 0;
168 
169  virtual void clear( void ) = 0;
170 
171  virtual void clear_trajectories( void ) = 0;
172 
173  virtual void clear_trajectory( size_t a ) = 0;
174 
175  virtual void reserve( size_t size ) = 0;
176 
177  virtual void build_trajectory_density_field( MeshScalarField &tdens ) const = 0;
178 
179  virtual void iterate_trajectories( MeshScalarField &scharge, const VectorField &efield,
180  const VectorField &bfield ) = 0;
181 
182  virtual void step_particles( MeshScalarField &scharge, const VectorField &efield,
183  const VectorField &bfield, double dt ) = 0;
184 
185  void debug_print( std::ostream &os ) const;
186 };
187 
188 
189 template<class PP> class ParticleDataBasePPImp : public ParticleDataBaseImp {
190 
193  static void add_diagnostics( TrajectoryDiagnosticData &tdata, const PP &x,
194  const Particle<PP> &p, int crd, int index ) {
195  //std::cout << "add_diagnostics():\n";
196  for( size_t a = 0; a < tdata.diag_size(); a++ ) {
197  //std::cout << " diagnostic[" << a << "] = " << tdata.diagnostic(a) << "\n";
198 
199  double data = 0.0;
200  switch( tdata.diagnostic( a ) ) {
201  case DIAG_NONE:
202  data = 0.0;
203  break;
204  case DIAG_T:
205  data = x[0];
206  break;
207  case DIAG_X:
208  data = x[1];
209  break;
210  case DIAG_VX:
211  data = x[2];
212  break;
213  case DIAG_Y:
214  case DIAG_R:
215  data = x[3];
216  break;
217  case DIAG_VY:
218  case DIAG_VR:
219  data = x[4];
220  break;
221  case DIAG_Z:
222  data = x[5];
223  break;
224  case DIAG_VZ:
225  data = x[6];
226  break;
227  case DIAG_W:
228  data = x[5];
229  break;
230  case DIAG_VTHETA:
231  data = x[5]*x[3];
232  break;
233  case DIAG_XP:
234  data = x[2]/x[2*crd+2];
235  break;
236  case DIAG_YP:
237  case DIAG_RP:
238  data = x[4]/x[2*crd+2];
239  break;
240  case DIAG_AP:
241  data = x[3]*x[5]/x[2*crd+2];
242  break;
243  case DIAG_ZP:
244  data = x[6]/x[2*crd+2];
245  break;
246  case DIAG_CURR:
247  data = p.IQ();
248  break;
249  case DIAG_QM:
250  data = (p.q()/CHARGE_E) / (p.m()/MASS_U);
251  break;
252  case DIAG_CHARGE:
253  data = p.q()/CHARGE_E;
254  break;
255  case DIAG_MASS:
256  data = p.m()/MASS_U;
257  break;
258  case DIAG_EK:
259  {
260  double beta = x.velocity().norm2()/SPEED_C;
261  if( beta < 1.0e-4 )
262  data = 0.5*p.m()*x.velocity().ssqr()/CHARGE_E;
263  else if( beta >= 1.0 )
264  throw( ErrorUnimplemented( ERROR_LOCATION, "particle velocity over light speed" ) );
265  else {
266  double gamma = 1.0 / sqrt( 1.0 - beta*beta );
267  double Ek = p.m()*SPEED_C2*( gamma - 1.0 );
268  data = Ek/CHARGE_E;
269  }
270  break;
271  }
272  case DIAG_NO:
273  data = index;
274  break;
275  default:
277  break;
278  }
279  //std::cout << " adding data = " << data << "\n";
280  tdata.add_data( a, data );
281  }
282  }
283 
284 protected:
285 
286  std::vector<Particle<PP> *> _particles;
293  if( _geom.geom_mode() != PP::geom_mode() )
294  throw( Error( ERROR_LOCATION, "Differing geometry modes" ) );
295  }
296 
299  ParticleDataBasePPImp( ParticleDataBase *pdb, std::istream &s, const Geometry &geom )
300  : ParticleDataBaseImp(pdb,s,geom), _scheduler(_particles) {
301 
302  uint32_t N = read_int32( s );
303  ibsimu.message( 1 ) << "Reading " << N << " particles.\n";
304  _particles.reserve( N );
305  for( uint32_t a = 0; a < N; a++ )
306  _particles.push_back( new Particle<PP>( s ) );
307 
308  ibsimu.dec_indent();
309  }
310 
315 
316  _particles.reserve( pdb._particles.size() );
317  for( size_t a = 0; a < pdb._particles.size(); a++ )
318  _particles.push_back( new Particle<PP>( *pdb._particles[a] ) );
319  }
320 
324 
325  for( size_t a; a < pdb._particles.size(); a++ )
326  delete _particles[a];
327  _particles.clear();
328  _particles.reserve( pdb._particles.size() );
329  for( size_t a = 0; a < pdb._particles.size(); a++ )
330  _particles.push_back( new Particle<PP>( *pdb._particles[a] ) );
331  return( *this );
332  }
333 
334 public:
335 
336  virtual ~ParticleDataBasePPImp() {
337  // Delete particles
338  for( size_t a = 0; a < _particles.size(); a++ )
339  delete( _particles[a] );
340  }
341 
342  virtual geom_mode_e geom_mode() const {
343  return( PP::geom_mode() );
344  }
345 
346  virtual size_t size( void ) const {
347  return( _particles.size() );
348  }
349 
350  Particle<PP> &particle( uint32_t i ) {
351  return( *_particles[i] );
352  }
353 
354  const Particle<PP> &particle( uint32_t i ) const {
355  return( *_particles[i] );
356  }
357 
358  virtual double traj_length( uint32_t i ) const {
359 
360  size_t N = _particles[i]->traj_size();
361  double len = 0.0;
362  if( N < 2 )
363  return( 0.0 );
364  Vec3D x1 = _particles[i]->traj(0).location();
365  for( size_t b = 1; b < N; b++ ) {
366  Vec3D x2 = _particles[i]->traj(b).location();
367  len += norm2(x2-x1);
368  x1 = x2;
369  }
370 
371  return( len );
372  }
373 
374  virtual size_t traj_size( uint32_t i ) const {
375  return( _particles[i]->traj_size() );
376  }
377 
378  const PP &trajectory_point( uint32_t i, uint32_t j ) const {
379  return( _particles[i]->traj(j) );
380  }
381 
382  virtual void trajectory_point( double &t, Vec3D &loc, Vec3D &vel, uint32_t i, uint32_t j ) const {
383  PP x = _particles[i]->traj(j);
384  t = x[0];
385  loc = x.location();
386  vel = x.velocity();
387  }
388 
389  virtual void trajectories_at_plane( std::vector< Particle<PP> > &tdata,
390  coordinate_axis_e axis,
391  double val ) const {
392 
393  ibsimu.message( 1 ) << "Making trajectory diagnostics at "
394  << coordinate_axis_string[axis] << " = " << val << "\n";
395  ibsimu.inc_indent();
396 
397  // Check query
398  switch( PP::geom_mode() ) {
399  case MODE_1D:
400  throw( Error( ERROR_LOCATION, "unsupported dimension number" ) );
401  break;
402  case MODE_2D:
403  if( axis == AXIS_R || axis == AXIS_Z )
404  throw( Error( ERROR_LOCATION, "nonexistent axis" ) );
405  break;
406  case MODE_CYL:
407  if( axis == AXIS_Y || axis == AXIS_Z )
408  throw( Error( ERROR_LOCATION, "nonexistent axis" ) );
409  break;
410  case MODE_3D:
411  if( axis == AXIS_R )
412  throw( Error( ERROR_LOCATION, "nonexistent axis" ) );
413  break;
414  default:
415  throw( Error( ERROR_LOCATION, "unsupported dimension number" ) );
416  }
417 
418  // Prepare output vector
419  tdata.clear();
420 
421  // Set coordinate index
422  int crd;
423  switch( axis ) {
424  case AXIS_X:
425  crd = 0;
426  break;
427  case AXIS_Y:
428  case AXIS_R:
429  crd = 1;
430  break;
431  case AXIS_Z:
432  crd = 2;
433  break;
434  default:
435  throw( Error( ERROR_LOCATION, "unsupported axis" ) );
436  }
437 
438  // Scan through particle trajectory points
439  double Isum = 0.0;
440  std::vector<PP> intsc;
441  for( size_t a = 0; a < _particles.size(); a++ ) {
442  size_t N = _particles[a]->traj_size();
443  if( N < 2 )
444  continue;
445  PP x1 = _particles[a]->traj(0);
446  for( size_t b = 1; b < N; b++ ) {
447  PP x2 = _particles[a]->traj(b);
448  intsc.clear();
449  size_t nintsc;
450  if( b == 1 )
451  nintsc = PP::trajectory_intersections_at_plane( intsc, crd, val, x1, x2, -1 );
452  else if( b == N-1 )
453  nintsc = PP::trajectory_intersections_at_plane( intsc, crd, val, x1, x2, +1 );
454  else
455  nintsc = PP::trajectory_intersections_at_plane( intsc, crd, val, x1, x2, 0 );
456  for( size_t c = 0; c < nintsc; c++ ) {
457  Isum += _particles[a]->IQ();
458  tdata.push_back( Particle<PP>( _particles[a]->IQ(), _particles[a]->q(),
459  _particles[a]->m(), intsc[c] ) );
460  }
461 
462  x1 = x2;
463  }
464  }
465 
466  ibsimu.message( 1 ) << "number of trajectories = " << tdata.size() << "\n";
467  if( PP::geom_mode() == MODE_2D )
468  ibsimu.message( 1 ) << "total current = " << Isum << " A/m\n";
469  else
470  ibsimu.message( 1 ) << "total current = " << Isum << " A\n";
471  ibsimu.dec_indent();
472  }
473 
474  virtual void trajectories_at_plane( TrajectoryDiagnosticData &tdata,
475  coordinate_axis_e axis,
476  double val,
477  const std::vector<trajectory_diagnostic_e> &diagnostics ) const {
478 
479  ibsimu.message( 1 ) << "Making trajectory diagnostics at "
480  << coordinate_axis_string[axis] << " = " << val << "\n";
481  ibsimu.inc_indent();
482 
483  // Check query
484  switch( PP::geom_mode() ) {
485  case MODE_1D:
486  throw( Error( ERROR_LOCATION, "unsupported dimension number" ) );
487  break;
488  case MODE_2D:
489  if( axis == AXIS_R || axis == AXIS_Z )
490  throw( Error( ERROR_LOCATION, "nonexistent axis" ) );
491  break;
492  case MODE_CYL:
493  if( axis == AXIS_Y || axis == AXIS_Z )
494  throw( Error( ERROR_LOCATION, "nonexistent axis" ) );
495  break;
496  case MODE_3D:
497  if( axis == AXIS_R )
498  throw( Error( ERROR_LOCATION, "nonexistent axis" ) );
499  break;
500  default:
501  throw( Error( ERROR_LOCATION, "unsupported dimension number" ) );
502  }
503 
504  // Check diagnostics query validity
505  for( size_t a = 0; a < diagnostics.size(); a++ ) {
506  if( diagnostics[a] == DIAG_NONE )
507  throw( Error( ERROR_LOCATION, "invalid diagnostics query \'DIAG_NONE\'" ) );
508  else if( PP::geom_mode() != MODE_CYL && (diagnostics[a] == DIAG_R ||
509  diagnostics[a] == DIAG_VR ||
510  diagnostics[a] == DIAG_RP ||
511  diagnostics[a] == DIAG_W ||
512  diagnostics[a] == DIAG_VTHETA ||
513  diagnostics[a] == DIAG_AP) )
514  throw( Error( ERROR_LOCATION, "invalid diagnostics query for geometry type" ) );
515  else if( PP::geom_mode() != MODE_3D && (diagnostics[a] == DIAG_Z ||
516  diagnostics[a] == DIAG_VZ ||
517  diagnostics[a] == DIAG_ZP) )
518  throw( Error( ERROR_LOCATION, "invalid diagnostics query for geometry type" ) );
519  else if( diagnostics[a] == DIAG_O ||
520  diagnostics[a] == DIAG_VO ||
521  diagnostics[a] == DIAG_OP ||
522  diagnostics[a] == DIAG_P ||
523  diagnostics[a] == DIAG_VP ||
524  diagnostics[a] == DIAG_PP ||
525  diagnostics[a] == DIAG_Q ||
526  diagnostics[a] == DIAG_VQ )
527  throw( Error( ERROR_LOCATION, "invalid diagnostics query for trajectories_at_plane()\n"
528  "use trajectories_at_free_plane()" ) );
529  }
530 
531  // Prepare output vector
532  tdata.clear();
533  for( size_t a = 0; a < diagnostics.size(); a++ ) {
534  tdata.add_data_column( diagnostics[a] );
535  }
536 
537  // Set coordinate index
538  int crd;
539  switch( axis ) {
540  case AXIS_X:
541  crd = 0;
542  break;
543  case AXIS_Y:
544  case AXIS_R:
545  crd = 1;
546  break;
547  case AXIS_Z:
548  crd = 2;
549  break;
550  default:
551  throw( Error( ERROR_LOCATION, "unsupported axis" ) );
552  }
553 
554  // Scan through particle trajectory points
555  double Isum = 0.0;
556  std::vector<PP> intsc;
557  for( size_t a = 0; a < _particles.size(); a++ ) {
558  size_t N = _particles[a]->traj_size();
559  if( N < 2 )
560  continue;
561  PP x1 = _particles[a]->traj(0);
562  for( size_t b = 1; b < N; b++ ) {
563  PP x2 = _particles[a]->traj(b);
564  intsc.clear();
565  size_t nintsc;
566  if( b == 1 )
567  nintsc = PP::trajectory_intersections_at_plane( intsc, crd, val, x1, x2, -1 );
568  else if( b == N-1 )
569  nintsc = PP::trajectory_intersections_at_plane( intsc, crd, val, x1, x2, +1 );
570  else
571  nintsc = PP::trajectory_intersections_at_plane( intsc, crd, val, x1, x2, 0 );
572  for( size_t c = 0; c < nintsc; c++ ) {
573  Isum += _particles[a]->IQ();
574  add_diagnostics( tdata, intsc[c], *_particles[a], crd, a );
575  }
576 
577  x1 = x2;
578  }
579  }
580 
581  ibsimu.message( 1 ) << "number of trajectories = " << tdata.traj_size() << "\n";
582  if( PP::geom_mode() == MODE_2D )
583  ibsimu.message( 1 ) << "total current = " << Isum << " A/m\n";
584  else
585  ibsimu.message( 1 ) << "total current = " << Isum << " A\n";
586  ibsimu.dec_indent();
587  }
588 
589  virtual void clear( void ) {
590  for( size_t a = 0; a < _particles.size(); a++ )
591  delete( _particles[a] );
592  _particles.clear();
593  _rhosum = 0.0;
594  }
595 
596  virtual void clear_trajectories( void ) {
597  for( uint32_t a = 0; a < _particles.size(); a++ )
598  _particles[a]->clear_trajectory();
599  }
600 
601  virtual void clear_trajectory( size_t a ) {
602  if( a >= _particles.size() )
603  throw( ErrorRange( ERROR_LOCATION, a, _particles.size() ) );
604  _particles[a]->clear_trajectory();
605  }
606 
607  virtual void reserve( size_t size ) {
608  _particles.reserve( size );
609  }
610 
611  void add_particle( const Particle<PP> &pp ) {
613  try {
614  _particles.push_back( new Particle<PP>( pp ) );
615  } catch( std::bad_alloc ) {
616  throw( ErrorNoMem( ERROR_LOCATION, "Out of memory adding particle" ) );
617  }
619  }
620 
621  void add_particle( double IQ, double q, double m, const PP &x ) {
622  add_particle( Particle<PP>( IQ, CHARGE_E*q, MASS_U*m, x ) );
623  }
624 
625  virtual void iterate_trajectories( MeshScalarField &scharge, const VectorField &efield,
626  const VectorField &bfield ) {
627 
628  Timer t;
629  ibsimu.message( 1 ) << "Calculating particle trajectories\n";
630  ibsimu.inc_indent();
631  if( _surface_collision )
632  ibsimu.message( 1 ) << "Using surface collision model\n";
633  else
634  ibsimu.message( 1 ) << "Using solid collision model\n";
635  if( _relativistic )
636  ibsimu.message( 1 ) << "Using relativistic iterator\n";
637  else
638  ibsimu.message( 1 ) << "Using non-relativistic iterator\n";
639  _iteration++;
640 
641  StatusPrint sp;
642  if( ibsimu.output_is_cout() ) {
643  std::stringstream ss;
644  ss << " " << "0 / " << _particles.size();
645  sp.print( ss.str() );
646  }
647 
648  // Check geometry mode
649  if( _geom.geom_mode() != PP::geom_mode() )
650  throw( Error( ERROR_LOCATION, "Differing geometry modes" ) );
651 
652  // Clear space charge
653  scharge.clear();
654 
655  // Reset statistics
656  _stat.reset( _geom.number_of_boundaries() );
657 
658  // Check number of particles
659  if( _particles.size() == 0 ) {
660  ibsimu.message( 1 ) << "no particles to calculate\n";
661  ibsimu.dec_indent();
662  return;
663  }
664 
665  // Make solvers
666  pthread_mutex_t scharge_mutex = PTHREAD_MUTEX_INITIALIZER;
667  std::vector<ParticleIterator<PP> *> iterators;
668  for( uint32_t a = 0; a < ibsimu.get_thread_count(); a++ ) {
669 
670  iterators.push_back( new ParticleIterator<PP>( PARTICLE_ITERATOR_ADAPTIVE, _epsabs, _epsrel,
672  _save_points, _trajdiv, _mirror, &scharge,
673  &scharge_mutex, &efield, &bfield, &_geom ) );
674  iterators[a]->set_trajectory_handler_callback( _thand_cb );
675  iterators[a]->set_trajectory_end_callback( _tend_cb, _pdb );
676  iterators[a]->set_trajectory_surface_collision_callback( _tsur_cb );
677  iterators[a]->set_bfield_suppression_callback( _bsup_cb );
678  iterators[a]->set_relativistic( _relativistic );
679  iterators[a]->set_surface_collision( _surface_collision );
680  }
681 
682  // Run scheduler
683  _scheduler.run( iterators );
684 
685  // Print statistics
686  if( ibsimu.output_is_cout() ) {
687  while( !_scheduler.wait_finish() ) {
688  std::stringstream ss;
689  ss << " " << _scheduler.get_solved_count() << " / "
691  sp.print( ss.str() );
692  }
693  }
694 
695  // Finish scheduler
696  _scheduler.finish();
697 
698  // Print final statistics
699  if( ibsimu.output_is_cout() ) {
700  std::stringstream ss;
701  ss << " " << _scheduler.get_solved_count() << " / "
702  << _scheduler.get_problem_count() << " Done\n";
703  sp.print( ss.str(), true );
704  }
705 
706  if( _scheduler.is_error() ) {
707  // Throw the error
708  std::vector<Error> err;
709  std::vector<int32_t> part;
710  _scheduler.get_errors( err, part );
711  throw( err[0] );
712  }
713 
714  // Collect statistics. Free all allocated memory.
715  for( uint32_t a = 0; a < ibsimu.get_thread_count(); a++ ) {
716  ParticleStatistics stat = iterators[a]->get_statistics();
717  _stat += stat;
718  delete iterators[a];
719  }
720 
722  scharge_finalize_linear( scharge );
723  else
724  scharge_finalize_pic( scharge );
725 
726  t.stop();
727  ibsimu.message( 1 ) << "Particle histories (" << _particles.size() << " total):\n";
728  ibsimu.message( 1 ) << " flown = " << _stat.bound_collisions() << "\n";
729  ibsimu.message( 1 ) << " time limited = " << _stat.end_time() << "\n";
730  ibsimu.message( 1 ) << " step count limited = " << _stat.end_step() << "\n";
731  ibsimu.message( 1 ) << " bad definitions = " << _stat.end_baddef() << "\n";
732  for( size_t a = 1; a <= _stat.number_of_boundaries(); a++ ) {
733  ibsimu.message( 1 ) << " beam to boundary " << a << " = " << _stat.bound_current(a)
734  << " " << PP::IQ_unit() << " (" << _stat.bound_collisions(a) << " particles)" << "\n";
735  }
736  ibsimu.message( 1 ) << " total steps = " << _stat.sum_steps() << "\n";
737  ibsimu.message( 1 ) << " steps per particle (ave) = " <<
738  _stat.sum_steps()/(double)_particles.size() << "\n";
739  ibsimu.message( 1 ) << "time used = " << t << "\n";
740  ibsimu.dec_indent();
741  }
742 
743  virtual void step_particles( MeshScalarField &scharge, const VectorField &efield,
744  const VectorField &bfield, double dt ) {
745 
747  }
748 
749 
750  void save( std::ostream &os ) const {
751 
752  ParticleDataBaseImp::save( os );
753 
754  write_int32( os, _particles.size() );
755  for( uint32_t a = 0; a < _particles.size(); a++ )
756  _particles[a]->save( os );
757  }
758 
759 
760  void debug_print( std::ostream &os ) const {
761  ParticleDataBaseImp::debug_print( os );
762 
763  for( uint32_t a = 0; a < _particles.size(); a++ ) {
764  os << "Particle " << a << ":\n";
765  _particles[a]->debug_print( os );
766  }
767  }
768 
769 };
770 
771 
776 class ParticleDataBase2DImp : public ParticleDataBasePPImp<ParticleP2D> {
777 
778  void add_tdens_from_segment( MeshScalarField &tdens, double IQ,
779  ParticleP2D &x1, ParticleP2D &x2 ) const;
780 
781 public:
782 
783  ParticleDataBase2DImp( ParticleDataBase *pdb, const Geometry &geom );
784 
786 
787  ParticleDataBase2DImp( ParticleDataBase *pdb, std::istream &s, const Geometry &geom );
788 
789  virtual ~ParticleDataBase2DImp();
790 
791  const ParticleDataBase2DImp &operator=( const ParticleDataBase2DImp &pdb );
792 
793  virtual void build_trajectory_density_field( MeshScalarField &tdens ) const;
794 
795  void add_2d_beam_with_velocity( uint32_t N, double J, double q, double m,
796  double v, double dvp, double dvt,
797  double x1, double y1, double x2, double y2 );
798 
799  void add_2d_beam_with_energy( uint32_t N, double J, double q, double m,
800  double E, double Tp, double Tt,
801  double x1, double y1, double x2, double y2 );
802 
803  void add_2d_KV_beam_with_emittance( uint32_t N, double I, double q, double m,
804  double a, double b, double e,
805  double Ex, double x0, double y0 );
806 
807  void add_2d_gaussian_beam_with_emittance( uint32_t N, double I, double q, double m,
808  double a, double b, double e,
809  double Ex, double x0, double y0 );
810 
811  void save( std::ostream &os ) const;
812 
813  void debug_print( std::ostream &os ) const;
814 };
815 
816 
817 
822 class ParticleDataBaseCylImp : public ParticleDataBasePPImp<ParticlePCyl> {
823 
824  void add_tdens_from_segment( MeshScalarField &tdens, double IQ,
825  ParticlePCyl &x1, ParticlePCyl &x2 ) const;
826 
827  static uint32_t bisect_cumulative_array( const std::vector<double> &cum, double x );
828 
829 public:
830 
831  ParticleDataBaseCylImp( ParticleDataBase *pdb, const Geometry &geom );
832 
834 
835  ParticleDataBaseCylImp( ParticleDataBase *pdb, std::istream &s, const Geometry &geom );
836 
837  virtual ~ParticleDataBaseCylImp();
838 
839  const ParticleDataBaseCylImp &operator=( const ParticleDataBaseCylImp &pdb );
840 
841  virtual void build_trajectory_density_field( MeshScalarField &tdens ) const;
842 
843  void add_2d_beam_with_total_energy( uint32_t N, double J, double q, double m,
844  double Etot, const ScalarField &epot,
845  double Tp, double Tt,
846  double x1, double y1, double x2, double y2 );
847 
848  void add_2d_beam_with_energy( uint32_t N, double J, double q, double m,
849  double E, double Tp, double Tt,
850  double x1, double y1, double x2, double y2 );
851 
852  void add_2d_beam_with_velocity( uint32_t N, double J, double q, double m,
853  double v, double dvp, double dvt,
854  double x1, double y1, double x2, double y2 );
855 
856  void add_2d_full_gaussian_beam( uint32_t N, double I, double q, double m,
857  double Ex, double Tp, double Tt,
858  double x0, double dr );
859 
860  void add_2d_gaussian_beam_with_emittance( uint32_t N, double I, double q, double m,
861  double a, double b, double e,
862  double Ex, double x0 );
863 
864  void export_path_manager_data( const std::string &filename,
865  double ref_E, double ref_q, double ref_m,
866  double val, uint32_t Np ) const;
867 
868  void save( std::ostream &os ) const;
869 
870  void debug_print( std::ostream &os ) const;
871 };
872 
873 
878 class ParticleDataBase3DImp : public ParticleDataBasePPImp<ParticleP3D> {
879 
880  void add_tdens_from_segment( MeshScalarField &tdens, double IQ,
881  ParticleP3D &x1, ParticleP3D &x2 ) const;
882 
883  bool free_plane_mirror_enabled( uint32_t axism ) const;
884  ParticleP3D free_plane_mirror( const ParticleP3D &p, uint32_t axism ) const;
885 public:
886 
887  ParticleDataBase3DImp( ParticleDataBase *pdb, const Geometry &geom );
888 
890 
891  ParticleDataBase3DImp( ParticleDataBase *pdb, std::istream &s, const Geometry &geom );
892 
893  virtual ~ParticleDataBase3DImp();
894 
895  const ParticleDataBase3DImp &operator=( const ParticleDataBase3DImp &pdb );
896 
897  virtual void build_trajectory_density_field( MeshScalarField &tdens ) const;
898 
899  void add_cylindrical_beam_with_total_energy( uint32_t N, double J, double q, double m,
900  double Etot, const ScalarField &epot,
901  double Tp, double Tt, Vec3D c,
902  Vec3D dir1, Vec3D dir2, double r );
903 
904  void add_cylindrical_beam_with_energy( uint32_t N, double J, double q, double m,
905  double E, double Tp, double Tt, Vec3D c,
906  Vec3D dir1, Vec3D dir2, double r );
907 
908  void add_cylindrical_beam_with_velocity( uint32_t N, double J, double q, double m,
909  double v, double dvp, double dvt, Vec3D c,
910  Vec3D dir1, Vec3D dir2, double r );
911 
912  void add_rectangular_beam_with_energy( uint32_t N, double J, double q, double m,
913  double E, double Tp, double Tt, Vec3D c,
914  Vec3D dir1, Vec3D dir2, double size1, double size2 );
915 
916  void add_rectangular_beam_with_velocity( uint32_t N, double J, double q, double m,
917  double v, double dvp, double dvt, Vec3D c,
918  Vec3D dir1, Vec3D dir2, double size1, double size2 );
919 
920  void add_3d_KV_beam_with_emittance( uint32_t N, double I, double q, double m,
921  double E0,
922  double a1, double b1, double e1,
923  double a2, double b2, double e2,
924  Vec3D c, Vec3D dir1, Vec3D dir2 );
925 
926  void add_3d_waterbag_beam_with_emittance( uint32_t N, double I, double q, double m,
927  double E0,
928  double a1, double b1, double e1,
929  double a2, double b2, double e2,
930  Vec3D c, Vec3D dir1, Vec3D dir2 );
931 
932  void add_3d_gaussian_beam_with_emittance( uint32_t N, double I, double q, double m,
933  double E0,
934  double a1, double b1, double e1,
935  double a2, double b2, double e2,
936  Vec3D c, Vec3D dir1, Vec3D dir2 );
937 
938  void trajectories_at_free_plane( TrajectoryDiagnosticData &tdata,
939  Vec3D c, Vec3D o, Vec3D p,
940  const std::vector<trajectory_diagnostic_e> &diagnostics ) const;
941 
942  void export_path_manager_data( const std::string &filename,
943  double ref_E, double ref_q, double ref_m,
944  Vec3D c, Vec3D o, Vec3D p ) const;
945 
946  void save( std::ostream &os ) const;
947 
948  void debug_print( std::ostream &os ) const;
949 };
950 
951 
952 #endif
953 
, where direction q is normal to diagnostic plane (rad)
Definition: types.hpp:217
, where direction q is normal to diagnostic plane (rad)
Definition: types.hpp:218
Particle point class for cylindrical coordinates.
Definition: particles.hpp:274
void inc_indent(void)
Increase message indentation.
Definition: ibsimu.cpp:136
Scheduler class for implementing consumer-producer threading.
Definition: scheduler.hpp:87
Basic error class.
Definition: error.hpp:142
Trajectory diagnostics.
void run(std::vector< Solv * > solv)
Run threads with N solvers.
Definition: scheduler.hpp:467
bool _surface_collision
Surface collision model.
Definition: particledatabaseimp.hpp:78
Vector field.
Definition: vectorfield.hpp:56
uint32_t get_solved_count(void)
Return number of solved problems.
Definition: scheduler.hpp:420
TrajectorySurfaceCollisionCallback * _tsur_cb
Trajectory surface collision callback.
Definition: particledatabaseimp.hpp:83
Q-axis position (m)
Definition: types.hpp:213
scharge_deposition_e _scharge_dep
Space charge deposition type.
Definition: particledatabaseimp.hpp:64
const CallbackFunctorD_V * _bsup_cb
Location dependent magnetic field suppression.
Definition: particledatabaseimp.hpp:80
double _maxt
Maximum particle time in simulation.
Definition: particledatabaseimp.hpp:66
uint32_t _trajdiv
Divisor for saved trajectories, if 3, every third trajectory is saved.
Definition: particledatabaseimp.hpp:68
Particle point class for 3D.
Definition: particles.hpp:458
Bindary file writing and reading tools.
, where direction q is normal to diagnostic plane (rad)
Definition: types.hpp:221
O-axis position (m)
Definition: types.hpp:209
uint32_t get_problem_count(void)
Return number of problems.
Definition: scheduler.hpp:430
Radial velocity (m/s)
Definition: types.hpp:204
void clear()
Clear all data and diagnostic types.
Definition: trajectorydiagnostics.hpp:154
Particle and particle point objects
TrajectoryEndCallback * _tend_cb
Trajectory collision callback.
Definition: particledatabaseimp.hpp:82
uint32_t _iteration
Iteration number.
Definition: particledatabaseimp.hpp:76
Particle mass (u)
Definition: types.hpp:226
void lock_mutex(void)
Lock mutex for adding problems.
Definition: scheduler.hpp:494
Kinetic energy (eV)
Definition: types.hpp:223
trajectory_interpolation_e _intrp
Trajectory interpolation type.
Definition: particledatabaseimp.hpp:63
geom_mode_e
Geometry mode enum.
Definition: types.hpp:59
ParticleDataBase2D implementation.
Definition: particledatabaseimp.hpp:776
uint32_t number_of_boundaries() const
Return number of boundaries.
Definition: geometry.cpp:285
bool is_error(void)
Return true on errors.
Definition: scheduler.hpp:404
X-axis velocity (m/s)
Definition: types.hpp:200
P-axis velocity (m/s)
Definition: types.hpp:212
Deposition to nodes as a linear function of distance to closet trajectory segment.
Definition: types.hpp:163
2D geometry
Definition: types.hpp:61
A tool for printing running status on command line.
Definition: statusprint.hpp:53
Trajectory end callback.
Definition: particledatabase.hpp:71
void dec_indent(void)
Decrease message indentation.
Definition: ibsimu.cpp:143
bool _mirror[6]
Boundary particle mirroring.
Definition: particledatabaseimp.hpp:70
Particle iterator class for continuous Vlasov-type iteration.
Definition: particleiterator.hpp:280
static double energy_to_velocity(double E, double m)
Convert energy to velocity.
Definition: particledatabaseimp.cpp:118
void add_data(size_t i, double x)
Add data point to i:th diagnostic column.
Definition: trajectorydiagnostics.hpp:212
Scalar field class.
Definition: meshscalarfield.hpp:70
bool wait_finish(void)
Call for solvers to finish when problems are solved.
Definition: scheduler.hpp:528
Y axis.
Definition: types.hpp:172
Scheduler< ParticleIterator< PP >, Particle< PP >, Error > _scheduler
Scheduler for solver.
Definition: particledatabaseimp.hpp:287
, where direction q is normal to diagnostic plane (rad)
Definition: types.hpp:216
Z-axis position (m)
Definition: types.hpp:207
ParticleStatistics _stat
Particle statistics.
Definition: particledatabaseimp.hpp:74
Trajectory handler callback.
Definition: particledatabase.hpp:58
std::ostream & message(message_type_e type, int32_t level)
Print message output.
Definition: ibsimu.cpp:111
size_t diag_size() const
Return number of data columns.
Definition: trajectorydiagnostics.hpp:166
Geometry defining class.
Definition: geometry.hpp:179
const char * coordinate_axis_string[]
String describing axis names without unit.
Definition: types.cpp:46
#define ERROR_LOCATION
Macro for setting error location when throwing errors.
Definition: error.hpp:72
uint32_t _maxsteps
Maximum number of steps to calculate.
Definition: particledatabaseimp.hpp:65
Y-axis velocity (m/s)
Definition: types.hpp:203
Particle index number. Useful for debugging.
Definition: types.hpp:227
Definition: callback.hpp:61
Time (s)
Definition: types.hpp:198
P-axis position (m)
Definition: types.hpp:211
Class for trajectory diagnostic data.
Definition: trajectorydiagnostics.hpp:127
R axis.
Definition: types.hpp:173
Subroutine for printing running status line on command line.
size_t traj_size() const
Return number of trajectories in data.
Definition: trajectorydiagnostics.hpp:172
Tangential velocity (m/s)
Definition: types.hpp:206
X-axis position (m)
Definition: types.hpp:199
ParticleDataBaseCyl implementation.
Definition: particledatabaseimp.hpp:822
Particle class in some geometry.
Definition: particles.hpp:739
void write_int32(std::ostream &s, int32_t value)
Write int32_t value into stream os.
Definition: file.cpp:70
void clear()
Clears the field.
Definition: meshscalarfield.cpp:121
void add_data_column(trajectory_diagnostic_e diag)
Add data column with type diag.
Definition: trajectorydiagnostics.hpp:160
double _epsabs
Absolute error limit for calculation.
Definition: particledatabaseimp.hpp:61
Definition: particledatabaseimp.hpp:56
scharge_deposition_e
Space charge depostition type.
Definition: types.hpp:161
Particle iteration statistics.
Definition: particlestatistics.hpp:57
void scharge_finalize_pic(MeshScalarField &scharge)
Finalize space charge calculation.
Definition: scharge.cpp:64
Particle point class for 2D.
Definition: particles.hpp:102
void print(const std::string &str, bool force=false)
Print str to output.
Definition: statusprint.cpp:66
Error class to use if requested feature is unimplemented.
Definition: error.hpp:218
, where direction q is normal to diagnostic plane (rad)
Definition: types.hpp:219
const ParticleDataBasePPImp & operator=(const ParticleDataBasePPImp &pdb)
Copy assignment operator.
Definition: particledatabaseimp.hpp:323
IBSimu ibsimu
Global instance of class IBSimu.
Definition: ibsimu.cpp:289
ParticleDataBase * _pdb
Particle database pointer.
Definition: particledatabaseimp.hpp:84
Error class for memory allocation errors.
Definition: error.hpp:185
Radial position (m)
Definition: types.hpp:202
ParticleDataBase3D implementation.
Definition: particledatabaseimp.hpp:878
bool _relativistic
Relativistic particle iteration.
Definition: particledatabaseimp.hpp:77
Timer for cputime and realtime
bool finish(void)
Wait for all problems to be solved.
Definition: scheduler.hpp:556
coordinate_axis_e
Coordinate axis identifier.
Definition: types.hpp:170
Current (I)
Definition: types.hpp:222
Error class for index range checking errors.
Definition: error.hpp:272
double _rhosum
Sum of space charge density in defined beams (C/m3).
Definition: particledatabaseimp.hpp:72
double IQ() const
Return current or charge carried by trajectory or particle cloud [A/C].
Definition: particles.hpp:706
Charge per mass (e/u)
Definition: types.hpp:224
ParticleDataBasePPImp(ParticleDataBase *pdb, const Geometry &geom)
Constructor, using API pdb.
Definition: particledatabaseimp.hpp:291
X axis.
Definition: types.hpp:171
, where direction q is normal to diagnostic plane (rad)
Definition: types.hpp:215
Y-axis position (m)
Definition: types.hpp:201
TrajectoryHandlerCallback * _thand_cb
Trajectory handler callback.
Definition: particledatabaseimp.hpp:81
Particle charge (e)
Definition: types.hpp:225
uint32_t get_thread_count(void)
Get the number of threads used for calculation.
Definition: ibsimu.hpp:203
Z axis.
Definition: types.hpp:174
void stop(void)
Stop timer.
Definition: timer.cpp:61
Cylindrically symmetric geometry.
Definition: types.hpp:62
Z-axis velocity (m/s)
Definition: types.hpp:208
Three dimensional vector.
Definition: vec3d.hpp:58
ParticleDataBasePPImp(const ParticleDataBasePPImp &pdb)
Copy constructor.
Definition: particledatabaseimp.hpp:313
bool output_is_cout()
Return if message output file is stdout.
Definition: ibsimu.cpp:184
double q() const
Return particle charge (q) [C].
Definition: particles.hpp:710
Definition: particledatabaseimp.hpp:189
int32_t read_int32(std::istream &s)
Read int32_t from stream is.
Definition: file.cpp:135
Class for measuring code runtime in cpu time and realtime.
Definition: timer.hpp:54
double _epsrel
Relative error limit for calculation.
Definition: particledatabaseimp.hpp:62
Angular velocity (rad/s)
Definition: types.hpp:205
Dummy diagnostic. Does nothing.
Definition: types.hpp:197
trajectory_diagnostic_e diagnostic(size_t i) const
Return i:th diagnostic type.
Definition: trajectorydiagnostics.hpp:180
Trajectory surface collision callback.
Definition: particledatabase.hpp:86
ParticleDataBasePPImp(ParticleDataBase *pdb, std::istream &s, const Geometry &geom)
Constructor from stream, using API pdb.
Definition: particledatabaseimp.hpp:299
3D geometry
Definition: types.hpp:63
double norm2(const Vector &vec)
Definition: mvector.cpp:474
1D geometry
Definition: types.hpp:60
double m() const
Return particle mass (m) [kg].
Definition: particles.hpp:714
Scalar field.
Definition: scalarfield.hpp:55
, where direction q is normal to diagnostic plane (rad)
Definition: types.hpp:220
Q-axis velocity (m/s)
Definition: types.hpp:214
geom_mode_e geom_mode(void) const
Returns geometry mode.
Definition: mesh.hpp:108
Particle database base class.
Definition: particledatabase.hpp:191
trajectory_interpolation_e
Trajectory interpolation type.
Definition: types.hpp:153
size_t get_errors(Cont1 &e, Cont2 &pi)
Fetch errors and indices of corresponding problems.
Definition: scheduler.hpp:447
std::vector< Particle< PP > * > _particles
Particles.
Definition: particledatabaseimp.hpp:286
bool _save_points
Save all points?
Definition: particledatabaseimp.hpp:67
Particle iterator
Ion Beam Simulator global settings.
O-axis velocity (m/s)
Definition: types.hpp:210
void unlock_mutex(void)
Unlock mutex.
Definition: scheduler.hpp:502


Reference manual for Ion Beam Simulator 1.0.5new_solver
Generated by Doxygen 1.8.5 on Tue May 19 2015 09:15:42.