Navigation

Main Page
Download
Support
Installation
Tutorial
Examples
Reference Manual
   Version 1.0.6
      Class Index
      File List
   Version 1.0.5new_solver
   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,2015 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 reset_trajectories( void ) = 0;
176 
177  virtual void reset_trajectory( size_t a ) = 0;
178 
179  virtual void reserve( size_t size ) = 0;
180 
181  virtual void build_trajectory_density_field( MeshScalarField &tdens ) const = 0;
182 
183  virtual void iterate_trajectories( MeshScalarField &scharge, const VectorField &efield,
184  const VectorField &bfield ) = 0;
185 
186  virtual void step_particles( MeshScalarField &scharge, const VectorField &efield,
187  const VectorField &bfield, double dt ) = 0;
188 
189  void debug_print( std::ostream &os ) const;
190 };
191 
192 
193 template<class PP> class ParticleDataBasePPImp : public ParticleDataBaseImp {
194 
197  static void add_diagnostics( TrajectoryDiagnosticData &tdata, const PP &x,
198  const Particle<PP> &p, int crd, int index ) {
199  //std::cout << "add_diagnostics():\n";
200  for( size_t a = 0; a < tdata.diag_size(); a++ ) {
201  //std::cout << " diagnostic[" << a << "] = " << tdata.diagnostic(a) << "\n";
202 
203  double data = 0.0;
204  switch( tdata.diagnostic( a ) ) {
205  case DIAG_NONE:
206  data = 0.0;
207  break;
208  case DIAG_T:
209  data = x[0];
210  break;
211  case DIAG_X:
212  data = x[1];
213  break;
214  case DIAG_VX:
215  data = x[2];
216  break;
217  case DIAG_Y:
218  case DIAG_R:
219  data = x[3];
220  break;
221  case DIAG_VY:
222  case DIAG_VR:
223  data = x[4];
224  break;
225  case DIAG_Z:
226  data = x[5];
227  break;
228  case DIAG_VZ:
229  data = x[6];
230  break;
231  case DIAG_W:
232  data = x[5];
233  break;
234  case DIAG_VTHETA:
235  data = x[5]*x[3];
236  break;
237  case DIAG_XP:
238  data = x[2]/x[2*crd+2];
239  break;
240  case DIAG_YP:
241  case DIAG_RP:
242  data = x[4]/x[2*crd+2];
243  break;
244  case DIAG_AP:
245  data = x[3]*x[5]/x[2*crd+2];
246  break;
247  case DIAG_ZP:
248  data = x[6]/x[2*crd+2];
249  break;
250  case DIAG_CURR:
251  data = p.IQ();
252  break;
253  case DIAG_QM:
254  data = (p.q()/CHARGE_E) / (p.m()/MASS_U);
255  break;
256  case DIAG_CHARGE:
257  data = p.q()/CHARGE_E;
258  break;
259  case DIAG_MASS:
260  data = p.m()/MASS_U;
261  break;
262  case DIAG_EK:
263  {
264  double beta = x.velocity().norm2()/SPEED_C;
265  if( beta < 1.0e-4 )
266  data = 0.5*p.m()*x.velocity().ssqr()/CHARGE_E;
267  else if( beta >= 1.0 )
268  throw( ErrorUnimplemented( ERROR_LOCATION, "particle velocity over light speed" ) );
269  else {
270  double gamma = 1.0 / sqrt( 1.0 - beta*beta );
271  double Ek = p.m()*SPEED_C2*( gamma - 1.0 );
272  data = Ek/CHARGE_E;
273  }
274  break;
275  }
276  case DIAG_NO:
277  data = index;
278  break;
279  default:
281  break;
282  }
283  //std::cout << " adding data = " << data << "\n";
284  tdata.add_data( a, data );
285  }
286  }
287 
288 protected:
289 
290  std::vector<Particle<PP> *> _particles;
297  if( _geom.geom_mode() != PP::geom_mode() )
298  throw( Error( ERROR_LOCATION, "Differing geometry modes" ) );
299  }
300 
303  ParticleDataBasePPImp( ParticleDataBase *pdb, std::istream &s, const Geometry &geom )
304  : ParticleDataBaseImp(pdb,s,geom), _scheduler(_particles) {
305 
306  uint32_t N = read_int32( s );
307  ibsimu.message( 1 ) << "Reading " << N << " particles.\n";
308  _particles.reserve( N );
309  for( uint32_t a = 0; a < N; a++ )
310  _particles.push_back( new Particle<PP>( s ) );
311 
312  ibsimu.dec_indent();
313  }
314 
319 
320  _particles.reserve( pdb._particles.size() );
321  for( size_t a = 0; a < pdb._particles.size(); a++ )
322  _particles.push_back( new Particle<PP>( *pdb._particles[a] ) );
323  }
324 
328 
329  for( size_t a; a < pdb._particles.size(); a++ )
330  delete _particles[a];
331  _particles.clear();
332  _particles.reserve( pdb._particles.size() );
333  for( size_t a = 0; a < pdb._particles.size(); a++ )
334  _particles.push_back( new Particle<PP>( *pdb._particles[a] ) );
335  return( *this );
336  }
337 
338 public:
339 
340  virtual ~ParticleDataBasePPImp() {
341  // Delete particles
342  for( size_t a = 0; a < _particles.size(); a++ )
343  delete( _particles[a] );
344  }
345 
346  virtual geom_mode_e geom_mode() const {
347  return( PP::geom_mode() );
348  }
349 
350  virtual size_t size( void ) const {
351  return( _particles.size() );
352  }
353 
354  Particle<PP> &particle( uint32_t i ) {
355  return( *_particles[i] );
356  }
357 
358  const Particle<PP> &particle( uint32_t i ) const {
359  return( *_particles[i] );
360  }
361 
362  virtual double traj_length( uint32_t i ) const {
363 
364  size_t N = _particles[i]->traj_size();
365  double len = 0.0;
366  if( N < 2 )
367  return( 0.0 );
368  Vec3D x1 = _particles[i]->traj(0).location();
369  for( size_t b = 1; b < N; b++ ) {
370  Vec3D x2 = _particles[i]->traj(b).location();
371  len += norm2(x2-x1);
372  x1 = x2;
373  }
374 
375  return( len );
376  }
377 
378  virtual size_t traj_size( uint32_t i ) const {
379  return( _particles[i]->traj_size() );
380  }
381 
382  const PP &trajectory_point( uint32_t i, uint32_t j ) const {
383  return( _particles[i]->traj(j) );
384  }
385 
386  virtual void trajectory_point( double &t, Vec3D &loc, Vec3D &vel, uint32_t i, uint32_t j ) const {
387  PP x = _particles[i]->traj(j);
388  t = x[0];
389  loc = x.location();
390  vel = x.velocity();
391  }
392 
393  virtual void trajectories_at_plane( std::vector< Particle<PP> > &tdata,
394  coordinate_axis_e axis,
395  double val ) const {
396 
397  ibsimu.message( 1 ) << "Making trajectory diagnostics at "
398  << coordinate_axis_string[axis] << " = " << val << "\n";
399  ibsimu.inc_indent();
400 
401  // Check query
402  switch( PP::geom_mode() ) {
403  case MODE_1D:
404  throw( Error( ERROR_LOCATION, "unsupported dimension number" ) );
405  break;
406  case MODE_2D:
407  if( axis == AXIS_R || axis == AXIS_Z )
408  throw( Error( ERROR_LOCATION, "nonexistent axis" ) );
409  break;
410  case MODE_CYL:
411  if( axis == AXIS_Y || axis == AXIS_Z )
412  throw( Error( ERROR_LOCATION, "nonexistent axis" ) );
413  break;
414  case MODE_3D:
415  if( axis == AXIS_R )
416  throw( Error( ERROR_LOCATION, "nonexistent axis" ) );
417  break;
418  default:
419  throw( Error( ERROR_LOCATION, "unsupported dimension number" ) );
420  }
421 
422  // Prepare output vector
423  tdata.clear();
424 
425  // Set coordinate index
426  int crd;
427  switch( axis ) {
428  case AXIS_X:
429  crd = 0;
430  break;
431  case AXIS_Y:
432  case AXIS_R:
433  crd = 1;
434  break;
435  case AXIS_Z:
436  crd = 2;
437  break;
438  default:
439  throw( Error( ERROR_LOCATION, "unsupported axis" ) );
440  }
441 
442  // Scan through particle trajectory points
443  double Isum = 0.0;
444  std::vector<PP> intsc;
445  for( size_t a = 0; a < _particles.size(); a++ ) {
446  size_t N = _particles[a]->traj_size();
447  if( N < 2 )
448  continue;
449  PP x1 = _particles[a]->traj(0);
450  for( size_t b = 1; b < N; b++ ) {
451  PP x2 = _particles[a]->traj(b);
452  intsc.clear();
453  size_t nintsc;
454  if( b == 1 )
455  nintsc = PP::trajectory_intersections_at_plane( intsc, crd, val, x1, x2, -1 );
456  else if( b == N-1 )
457  nintsc = PP::trajectory_intersections_at_plane( intsc, crd, val, x1, x2, +1 );
458  else
459  nintsc = PP::trajectory_intersections_at_plane( intsc, crd, val, x1, x2, 0 );
460  for( size_t c = 0; c < nintsc; c++ ) {
461  Isum += _particles[a]->IQ();
462  tdata.push_back( Particle<PP>( _particles[a]->IQ(), _particles[a]->q(),
463  _particles[a]->m(), intsc[c] ) );
464  }
465 
466  x1 = x2;
467  }
468  }
469 
470  ibsimu.message( 1 ) << "number of trajectories = " << tdata.size() << "\n";
471  if( PP::geom_mode() == MODE_2D )
472  ibsimu.message( 1 ) << "total current = " << Isum << " A/m\n";
473  else
474  ibsimu.message( 1 ) << "total current = " << Isum << " A\n";
475  ibsimu.dec_indent();
476  }
477 
478  virtual void trajectories_at_plane( TrajectoryDiagnosticData &tdata,
479  coordinate_axis_e axis,
480  double val,
481  const std::vector<trajectory_diagnostic_e> &diagnostics ) const {
482 
483  ibsimu.message( 1 ) << "Making trajectory diagnostics at "
484  << coordinate_axis_string[axis] << " = " << val << "\n";
485  ibsimu.inc_indent();
486 
487  // Check query
488  switch( PP::geom_mode() ) {
489  case MODE_1D:
490  throw( Error( ERROR_LOCATION, "unsupported dimension number" ) );
491  break;
492  case MODE_2D:
493  if( axis == AXIS_R || axis == AXIS_Z )
494  throw( Error( ERROR_LOCATION, "nonexistent axis" ) );
495  break;
496  case MODE_CYL:
497  if( axis == AXIS_Y || axis == AXIS_Z )
498  throw( Error( ERROR_LOCATION, "nonexistent axis" ) );
499  break;
500  case MODE_3D:
501  if( axis == AXIS_R )
502  throw( Error( ERROR_LOCATION, "nonexistent axis" ) );
503  break;
504  default:
505  throw( Error( ERROR_LOCATION, "unsupported dimension number" ) );
506  }
507 
508  // Check diagnostics query validity
509  for( size_t a = 0; a < diagnostics.size(); a++ ) {
510  if( diagnostics[a] == DIAG_NONE )
511  throw( Error( ERROR_LOCATION, "invalid diagnostics query \'DIAG_NONE\'" ) );
512  else if( PP::geom_mode() != MODE_CYL && (diagnostics[a] == DIAG_R ||
513  diagnostics[a] == DIAG_VR ||
514  diagnostics[a] == DIAG_RP ||
515  diagnostics[a] == DIAG_W ||
516  diagnostics[a] == DIAG_VTHETA ||
517  diagnostics[a] == DIAG_AP) )
518  throw( Error( ERROR_LOCATION, "invalid diagnostics query for geometry type" ) );
519  else if( PP::geom_mode() != MODE_3D && (diagnostics[a] == DIAG_Z ||
520  diagnostics[a] == DIAG_VZ ||
521  diagnostics[a] == DIAG_ZP) )
522  throw( Error( ERROR_LOCATION, "invalid diagnostics query for geometry type" ) );
523  else if( diagnostics[a] == DIAG_O ||
524  diagnostics[a] == DIAG_VO ||
525  diagnostics[a] == DIAG_OP ||
526  diagnostics[a] == DIAG_P ||
527  diagnostics[a] == DIAG_VP ||
528  diagnostics[a] == DIAG_PP ||
529  diagnostics[a] == DIAG_Q ||
530  diagnostics[a] == DIAG_VQ )
531  throw( Error( ERROR_LOCATION, "invalid diagnostics query for trajectories_at_plane()\n"
532  "use trajectories_at_free_plane()" ) );
533  }
534 
535  // Prepare output vector
536  tdata.clear();
537  for( size_t a = 0; a < diagnostics.size(); a++ ) {
538  tdata.add_data_column( diagnostics[a] );
539  }
540 
541  // Set coordinate index
542  int crd;
543  switch( axis ) {
544  case AXIS_X:
545  crd = 0;
546  break;
547  case AXIS_Y:
548  case AXIS_R:
549  crd = 1;
550  break;
551  case AXIS_Z:
552  crd = 2;
553  break;
554  default:
555  throw( Error( ERROR_LOCATION, "unsupported axis" ) );
556  }
557 
558  // Scan through particle trajectory points
559  double Isum = 0.0;
560  std::vector<PP> intsc;
561  for( size_t a = 0; a < _particles.size(); a++ ) {
562  size_t N = _particles[a]->traj_size();
563  if( N < 2 )
564  continue;
565  PP x1 = _particles[a]->traj(0);
566  for( size_t b = 1; b < N; b++ ) {
567  PP x2 = _particles[a]->traj(b);
568  intsc.clear();
569  size_t nintsc;
570  if( b == 1 )
571  nintsc = PP::trajectory_intersections_at_plane( intsc, crd, val, x1, x2, -1 );
572  else if( b == N-1 )
573  nintsc = PP::trajectory_intersections_at_plane( intsc, crd, val, x1, x2, +1 );
574  else
575  nintsc = PP::trajectory_intersections_at_plane( intsc, crd, val, x1, x2, 0 );
576  for( size_t c = 0; c < nintsc; c++ ) {
577  Isum += _particles[a]->IQ();
578  add_diagnostics( tdata, intsc[c], *_particles[a], crd, a );
579  }
580 
581  x1 = x2;
582  }
583  }
584 
585  ibsimu.message( 1 ) << "number of trajectories = " << tdata.traj_size() << "\n";
586  if( PP::geom_mode() == MODE_2D )
587  ibsimu.message( 1 ) << "total current = " << Isum << " A/m\n";
588  else
589  ibsimu.message( 1 ) << "total current = " << Isum << " A\n";
590  ibsimu.dec_indent();
591  }
592 
593  virtual void clear( void ) {
594  for( size_t a = 0; a < _particles.size(); a++ )
595  delete( _particles[a] );
596  _particles.clear();
597  _rhosum = 0.0;
598  }
599 
600  virtual void clear_trajectories( void ) {
601  for( uint32_t a = 0; a < _particles.size(); a++ )
602  _particles[a]->clear_trajectory();
603  }
604 
605  virtual void clear_trajectory( size_t a ) {
606  if( a >= _particles.size() )
607  throw( ErrorRange( ERROR_LOCATION, a, _particles.size() ) );
608  _particles[a]->clear_trajectory();
609  }
610 
611  virtual void reset_trajectories( void ) {
612  for( uint32_t a = 0; a < _particles.size(); a++ )
613  _particles[a]->reset_trajectory();
614  }
615 
616  virtual void reset_trajectory( size_t a ) {
617  if( a >= _particles.size() )
618  throw( ErrorRange( ERROR_LOCATION, a, _particles.size() ) );
619  _particles[a]->reset_trajectory();
620  }
621 
622  virtual void reserve( size_t size ) {
623  _particles.reserve( size );
624  }
625 
626  void add_particle( const Particle<PP> &pp ) {
628  try {
629  _particles.push_back( new Particle<PP>( pp ) );
630  } catch( std::bad_alloc ) {
631  throw( ErrorNoMem( ERROR_LOCATION, "Out of memory adding particle" ) );
632  }
634  }
635 
636  void add_particle( double IQ, double q, double m, const PP &x ) {
637  add_particle( Particle<PP>( IQ, CHARGE_E*q, MASS_U*m, x ) );
638  }
639 
640  virtual void iterate_trajectories( MeshScalarField &scharge, const VectorField &efield,
641  const VectorField &bfield ) {
642 
643  Timer t;
644  ibsimu.message( 1 ) << "Calculating particle trajectories\n";
645  ibsimu.inc_indent();
646  if( _surface_collision )
647  ibsimu.message( 1 ) << "Using surface collision model\n";
648  else
649  ibsimu.message( 1 ) << "Using solid collision model\n";
650  if( _relativistic )
651  ibsimu.message( 1 ) << "Using relativistic iterator\n";
652  else
653  ibsimu.message( 1 ) << "Using non-relativistic iterator\n";
654  _iteration++;
655 
656  StatusPrint sp;
657  if( ibsimu.output_is_cout() ) {
658  std::stringstream ss;
659  ss << " " << "0 / " << _particles.size();
660  sp.print( ss.str() );
661  }
662 
663  // Check geometry mode
664  if( _geom.geom_mode() != PP::geom_mode() )
665  throw( Error( ERROR_LOCATION, "Differing geometry modes" ) );
666 
667  // Clear space charge
668  scharge.clear();
669 
670  // Reset statistics
671  _stat.reset( _geom.number_of_boundaries() );
672 
673  // Check number of particles
674  if( _particles.size() == 0 ) {
675  ibsimu.message( 1 ) << "no particles to calculate\n";
676  ibsimu.dec_indent();
677  return;
678  }
679 
680  // Make solvers
681  pthread_mutex_t scharge_mutex = PTHREAD_MUTEX_INITIALIZER;
682  std::vector<ParticleIterator<PP> *> iterators;
683  for( uint32_t a = 0; a < ibsimu.get_thread_count(); a++ ) {
684 
685  iterators.push_back( new ParticleIterator<PP>( PARTICLE_ITERATOR_ADAPTIVE, _epsabs, _epsrel,
687  _save_points, _trajdiv, _mirror, &scharge,
688  &scharge_mutex, &efield, &bfield, &_geom ) );
689  iterators[a]->set_trajectory_handler_callback( _thand_cb );
690  iterators[a]->set_trajectory_end_callback( _tend_cb, _pdb );
691  iterators[a]->set_trajectory_surface_collision_callback( _tsur_cb );
692  iterators[a]->set_bfield_suppression_callback( _bsup_cb );
693  iterators[a]->set_relativistic( _relativistic );
694  iterators[a]->set_surface_collision( _surface_collision );
695  }
696 
697  // Run scheduler
698  _scheduler.run( iterators );
699 
700  // Print statistics
701  if( ibsimu.output_is_cout() ) {
702  while( !_scheduler.wait_finish() ) {
703  std::stringstream ss;
704  ss << " " << _scheduler.get_solved_count() << " / "
706  sp.print( ss.str() );
707  }
708  }
709 
710  // Finish scheduler
711  _scheduler.finish();
712 
713  // Print final statistics
714  if( ibsimu.output_is_cout() ) {
715  std::stringstream ss;
716  ss << " " << _scheduler.get_solved_count() << " / "
717  << _scheduler.get_problem_count() << " Done\n";
718  sp.print( ss.str(), true );
719  }
720 
721  if( _scheduler.is_error() ) {
722  // Throw the error
723  std::vector<Error> err;
724  std::vector<int32_t> part;
725  _scheduler.get_errors( err, part );
726  throw( err[0] );
727  }
728 
729  // Collect statistics. Free all allocated memory.
730  for( uint32_t a = 0; a < ibsimu.get_thread_count(); a++ ) {
731  ParticleStatistics stat = iterators[a]->get_statistics();
732  _stat += stat;
733  delete iterators[a];
734  }
735 
737  scharge_finalize_linear( scharge );
738  else
739  scharge_finalize_pic( scharge );
740 
741  t.stop();
742  ibsimu.message( 1 ) << "Particle histories (" << _particles.size() << " total):\n";
743  ibsimu.message( 1 ) << " flown = " << _stat.bound_collisions() << "\n";
744  ibsimu.message( 1 ) << " time limited = " << _stat.end_time() << "\n";
745  ibsimu.message( 1 ) << " step count limited = " << _stat.end_step() << "\n";
746  ibsimu.message( 1 ) << " bad definitions = " << _stat.end_baddef() << "\n";
747  for( size_t a = 1; a <= _stat.number_of_boundaries(); a++ ) {
748  ibsimu.message( 1 ) << " beam to boundary " << a << " = " << _stat.bound_current(a)
749  << " " << PP::IQ_unit() << " (" << _stat.bound_collisions(a) << " particles)" << "\n";
750  }
751  ibsimu.message( 1 ) << " total steps = " << _stat.sum_steps() << "\n";
752  ibsimu.message( 1 ) << " steps per particle (ave) = " <<
753  _stat.sum_steps()/(double)_particles.size() << "\n";
754  ibsimu.message( 1 ) << "time used = " << t << "\n";
755  ibsimu.dec_indent();
756  }
757 
758  virtual void step_particles( MeshScalarField &scharge, const VectorField &efield,
759  const VectorField &bfield, double dt ) {
760 
762  }
763 
764 
765  void save( std::ostream &os ) const {
766 
767  ParticleDataBaseImp::save( os );
768 
769  write_int32( os, _particles.size() );
770  for( uint32_t a = 0; a < _particles.size(); a++ )
771  _particles[a]->save( os );
772  }
773 
774 
775  void debug_print( std::ostream &os ) const {
776  ParticleDataBaseImp::debug_print( os );
777 
778  for( uint32_t a = 0; a < _particles.size(); a++ ) {
779  os << "Particle " << a << ":\n";
780  _particles[a]->debug_print( os );
781  }
782  }
783 
784 };
785 
786 
791 class ParticleDataBase2DImp : public ParticleDataBasePPImp<ParticleP2D> {
792 
793  void add_tdens_from_segment( MeshScalarField &tdens, double IQ,
794  ParticleP2D &x1, ParticleP2D &x2 ) const;
795 
796 public:
797 
798  ParticleDataBase2DImp( ParticleDataBase *pdb, const Geometry &geom );
799 
801 
802  ParticleDataBase2DImp( ParticleDataBase *pdb, std::istream &s, const Geometry &geom );
803 
804  virtual ~ParticleDataBase2DImp();
805 
806  const ParticleDataBase2DImp &operator=( const ParticleDataBase2DImp &pdb );
807 
808  virtual void build_trajectory_density_field( MeshScalarField &tdens ) const;
809 
810  void add_2d_beam_with_velocity( uint32_t N, double J, double q, double m,
811  double v, double dvp, double dvt,
812  double x1, double y1, double x2, double y2 );
813 
814  void add_2d_beam_with_energy( uint32_t N, double J, double q, double m,
815  double E, double Tp, double Tt,
816  double x1, double y1, double x2, double y2 );
817 
818  void add_2d_KV_beam_with_emittance( uint32_t N, double I, double q, double m,
819  double a, double b, double e,
820  double Ex, double x0, double y0 );
821 
822  void add_2d_gaussian_beam_with_emittance( uint32_t N, double I, double q, double m,
823  double a, double b, double e,
824  double Ex, double x0, double y0 );
825 
826  void save( std::ostream &os ) const;
827 
828  void debug_print( std::ostream &os ) const;
829 };
830 
831 
832 
837 class ParticleDataBaseCylImp : public ParticleDataBasePPImp<ParticlePCyl> {
838 
839  void add_tdens_from_segment( MeshScalarField &tdens, double IQ,
840  ParticlePCyl &x1, ParticlePCyl &x2 ) const;
841 
842  static uint32_t bisect_cumulative_array( const std::vector<double> &cum, double x );
843 
844 public:
845 
846  ParticleDataBaseCylImp( ParticleDataBase *pdb, const Geometry &geom );
847 
849 
850  ParticleDataBaseCylImp( ParticleDataBase *pdb, std::istream &s, const Geometry &geom );
851 
852  virtual ~ParticleDataBaseCylImp();
853 
854  const ParticleDataBaseCylImp &operator=( const ParticleDataBaseCylImp &pdb );
855 
856  virtual void build_trajectory_density_field( MeshScalarField &tdens ) const;
857 
858  void add_2d_beam_with_total_energy( uint32_t N, double J, double q, double m,
859  double Etot, const ScalarField &epot,
860  double Tp, double Tt,
861  double x1, double y1, double x2, double y2 );
862 
863  void add_2d_beam_with_energy( uint32_t N, double J, double q, double m,
864  double E, double Tp, double Tt,
865  double x1, double y1, double x2, double y2 );
866 
867  void add_2d_beam_with_velocity( uint32_t N, double J, double q, double m,
868  double v, double dvp, double dvt,
869  double x1, double y1, double x2, double y2 );
870 
871  void add_2d_full_gaussian_beam( uint32_t N, double I, double q, double m,
872  double Ex, double Tp, double Tt,
873  double x0, double dr );
874 
875  void add_2d_gaussian_beam_with_emittance( uint32_t N, double I, double q, double m,
876  double a, double b, double e,
877  double Ex, double x0 );
878 
879  void export_path_manager_data( const std::string &filename,
880  double ref_E, double ref_q, double ref_m,
881  double val, uint32_t Np ) const;
882 
883  void save( std::ostream &os ) const;
884 
885  void debug_print( std::ostream &os ) const;
886 };
887 
888 
893 class ParticleDataBase3DImp : public ParticleDataBasePPImp<ParticleP3D> {
894 
895  void add_tdens_from_segment( MeshScalarField &tdens, double IQ,
896  ParticleP3D &x1, ParticleP3D &x2 ) const;
897 
898  bool free_plane_mirror_enabled( uint32_t axism ) const;
899  ParticleP3D free_plane_mirror( const ParticleP3D &p, uint32_t axism ) const;
900 public:
901 
902  ParticleDataBase3DImp( ParticleDataBase *pdb, const Geometry &geom );
903 
905 
906  ParticleDataBase3DImp( ParticleDataBase *pdb, std::istream &s, const Geometry &geom );
907 
908  virtual ~ParticleDataBase3DImp();
909 
910  const ParticleDataBase3DImp &operator=( const ParticleDataBase3DImp &pdb );
911 
912  virtual void build_trajectory_density_field( MeshScalarField &tdens ) const;
913 
914  void add_cylindrical_beam_with_total_energy( uint32_t N, double J, double q, double m,
915  double Etot, const ScalarField &epot,
916  double Tp, double Tt, Vec3D c,
917  Vec3D dir1, Vec3D dir2, double r );
918 
919  void add_cylindrical_beam_with_energy( uint32_t N, double J, double q, double m,
920  double E, double Tp, double Tt, Vec3D c,
921  Vec3D dir1, Vec3D dir2, double r );
922 
923  void add_cylindrical_beam_with_velocity( uint32_t N, double J, double q, double m,
924  double v, double dvp, double dvt, Vec3D c,
925  Vec3D dir1, Vec3D dir2, double r );
926 
927  void add_rectangular_beam_with_energy( uint32_t N, double J, double q, double m,
928  double E, double Tp, double Tt, Vec3D c,
929  Vec3D dir1, Vec3D dir2, double size1, double size2 );
930 
931  void add_rectangular_beam_with_velocity( uint32_t N, double J, double q, double m,
932  double v, double dvp, double dvt, Vec3D c,
933  Vec3D dir1, Vec3D dir2, double size1, double size2 );
934 
935  void add_3d_KV_beam_with_emittance( uint32_t N, double I, double q, double m,
936  double E0,
937  double a1, double b1, double e1,
938  double a2, double b2, double e2,
939  Vec3D c, Vec3D dir1, Vec3D dir2 );
940 
941  void add_3d_waterbag_beam_with_emittance( uint32_t N, double I, double q, double m,
942  double E0,
943  double a1, double b1, double e1,
944  double a2, double b2, double e2,
945  Vec3D c, Vec3D dir1, Vec3D dir2 );
946 
947  void add_3d_gaussian_beam_with_emittance( uint32_t N, double I, double q, double m,
948  double E0,
949  double a1, double b1, double e1,
950  double a2, double b2, double e2,
951  Vec3D c, Vec3D dir1, Vec3D dir2 );
952 
953  void trajectories_at_free_plane( TrajectoryDiagnosticData &tdata,
954  Vec3D c, Vec3D o, Vec3D p,
955  const std::vector<trajectory_diagnostic_e> &diagnostics ) const;
956 
957  void export_path_manager_data( const std::string &filename,
958  double ref_E, double ref_q, double ref_m,
959  Vec3D c, Vec3D o, Vec3D p ) const;
960 
961  void save( std::ostream &os ) const;
962 
963  void debug_print( std::ostream &os ) const;
964 };
965 
966 
967 #endif
968 
, 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:791
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:125
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:291
, 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:837
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:327
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:893
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:295
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:317
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:193
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:303
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:290
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.6
Generated by Doxygen 1.8.5 on Mon Jun 15 2015 09:59:32.