.Simulation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
Simulation.h
1 
24 #ifndef __SIMULATION_SIMULATION_H__
25 #define __SIMULATION_SIMULATION_H__
26 
27 #include "../CellList/CellListFast.h"
28 #include "../EventCalendar/EventCalendar.h"
29 #include "../EventCalendar/EventType.h"
30 #include "../Particle/Particle.h"
31 #include "../RPK/RPK.h"
32 #include "../Vector/Vector.hpp"
33 
34 #include "./CollisionRecord.h"
35 #include "./Statistics.h"
36 
37 #include <math.h>
38 #include <vector>
39 
40 namespace MDSimulation
41 {
48  {
49  public:
50 
54  explicit AllParticles(const int)
55  { }
56 
61  inline bool operator()(const int)
62  {
63  return true;
64  }
65  };
66 
72  class LessThan
73  {
74  private:
75  const int Upper; // Strict upper bound of particles to accept.
76 
77  public:
81  explicit LessThan(const int i) : Upper(i)
82  { }
83 
88  inline bool operator()(const int pa)
89  {
90  return pa < Upper;
91  }
92  };
93 
100  class Skipping
101  {
102  private:
103  const int Skip; // Index value to skip.
104 
105  public:
110  explicit Skipping(const int s) : Skip(s)
111  { }
112 
117  inline bool operator()(const int pa)
118  {
119  return pa != Skip;
120  }
121  };
122 
130  {
131  private:
132 
133  // The number of radial bins to compute statistic for when writing a snapshot.
134  static const int MAX_BINS = 48;
135 
136  // The number of collisions to be recorded.
137  static const size_t COLLISION_RECORDS = 100000;
138 
139  typedef std::unique_ptr<EventCalendar> CalendarPtr;
140 
141  InfoStruct Info;
143  CellList Partitions;
144  CalendarPtr Calendar;
146  std::vector<Particle> Particles;
147  std::vector<double> ConeTime;
148  std::vector<double> WallTime;
149  double CurrentTime;
151  int ParticleCount;
152  int MaxParticles;
154  int SnapshotCount;
156  DoubleVector Extent;
157  DoubleVector Offset;
158  IntVector Cells;
159  IntVector InitUCell;
161  RPK RPKEquation;
162  double LastRebinRadius;
163  double LastVelocity;
164  double LastSnapshotTime;
165  bool Rebounded;
166  bool Save;
168  Statistics Stats;
169 
170  std::string OutDir;
171 
172  clock_t PerformanceClock;
173 
189  template <class Controller>
190  inline void PredictEvents(const int na, const int nb, const EventType ev);
191 
203  int CellCrossingTimes(const int na, DoubleVector& times);
204 
215  double ConeCollisionTime(const int na);
216 
224  double WallCollisionTime(const int na);
225 
243  template <class Controller>
244  void ScheduleParticleCollisions(const int na, Controller& con,
245  const IntVector& low,
246  const IntVector& high);
247 
254  template <class Controller>
255  void ScheduleParticleCollisions(const int na, Controller& con);
256 
266  double ComputeIntersectionTime(const Particle& pa, const Particle& pb);
267 
274  void ProcessCellCrossing();
275 
281  void ProcessBubbleWall();
282 
288  void ProcessCollision();
289 
302  void DissociateParticle(const int na);
303 
309  void ProcessCone();
310 
319  void ProcessUpdateSystem();
320 
328  void ProcessReadPGauge();
329 
340  double Diameter2(const double vv, const Particle& p1, const Particle& p2);
341 
348  void BinSystem();
349 
354  void StartRun();
355 
362  int ComputeParticlesInSystem() const;
363 
368  void InitializeParticles();
369 
370 
374  void PopulateCalendar();
375 
380  void WriteSnapshot();
381 
382 
388  void WriteCollisionEnergy();
389 
390  public:
391 
392  friend std::ostream& operator<<(std::ostream& stream, const Simulation& sim);
393 
404  explicit Simulation(const InfoStruct& info, const std::string& outDir = "", const bool save = true);
405 
410  void PurgeEvents();
411 
418  bool HasRebounded() const;
419 
425 
430  std::vector<Particle>::const_iterator begin();
431 
436  std::vector<Particle>::const_iterator end();
437 
442  double GetCurrentTime() const;
443 
447  unsigned long long GetCollisionCount() const;
448 
452  unsigned long long GetCellCrossingCount() const;
453 
457  unsigned long long GetWallCollisionCount() const;
458 
462  unsigned long long GetConeBoundaryCount() const;
463 
467  template <typename Writer>
468  void Serialize(Writer& writer) const;
469 
473  int GetParticleCount() const;
474 
475  // void Read(const boost::property_tree::ptree& tree);
476  };
477 
478  template <typename Controller>
479  void Simulation::PredictEvents(const int na, const int nb, const EventType ev)
480  {
481  Controller con(nb);
482  Particle& pa = Particles[na];
483  pa.UpdateParticle(this->CurrentTime);
484 
485  DoubleVector cellTime(0.0, 0.0, 0.0);
486 
487  const int evCode = this->CellCrossingTimes(na, cellTime);
488  cellTime[evCode] += this->CurrentTime;
489 
490  // Do not repredict cone wall and bubble wall events after a
491  // cell crossing event. The previous values are not invalidated by
492  // these events.
493  if (ev != CellCrossingEvent)
494  {
495  this->ConeTime[na] = this->ConeCollisionTime(na) + this->CurrentTime;
496 
497  // Do not repredict Bubble wall crossings after cone
498  // events, as cone wall events, supposedly, do not alter the
499  // radial velocity of the particles
500  if (ev != ConeWallEvent)
501  {
502  this->WallTime[na] = this->WallCollisionTime(na);
503  }
504  }
505 
506  // Find the nearest event for this particle and schedule.
507  if (cellTime[evCode] < this->ConeTime[na])
508  {
509  if (cellTime[evCode] < this->WallTime[na])
510  {
511  // Schedule a cell crossing event.
512  this->Calendar->ScheduleEvent(
513  cellTime[evCode], CellCrossingEvent, na, evCode);
514  }
515  else
516  {
517  // Schedule a bubble wall event. The second particle in bubble
518  // wall events is ignored.
519  this->Calendar->ScheduleEvent(
520  this->WallTime[na], BubbleWallEvent, na, -1);
521  }
522  }
523  else
524  {
525  if (this->ConeTime[na] < this->WallTime[na])
526  {
527  // Schedule a cone wall event. The second particle in cone
528  // wall events is ignored.
529  this->Calendar->ScheduleEvent(
530  this->ConeTime[na], ConeWallEvent, na, -1);
531  }
532  else
533  {
534  // Schedule a bubble wall event. The second particle in bubble
535  // wall events is ignored.
536  this->Calendar->ScheduleEvent(
537  this->WallTime[na], BubbleWallEvent, na, -1);
538  }
539  }
540 
541 
542  // If the last event was a cell crossing, we can limit the search to
543  // those in the direction we are heading, as we will have retained
544  // the collisions from particles within the current and previous
545  // cell.
546  IntVector low(-1, -1, -1);
547  IntVector high(1, 1, 1);
548 
549  // If a cell crossing just occurred, we can optimize by providing
550  // more restricted bounds on the neighborhood search.
551  if (ev == CellCrossingEvent)
552  {
553  if (pa.Velocity[nb] >= 0.0)
554  {
555  low[nb] = 1;
556  }
557  else
558  {
559  high[nb] = -1;
560  }
561  }
562 
563  this->ScheduleParticleCollisions<Controller>(na, con, low, high);
564  }
565 
566  template <typename Controller>
567  void Simulation::ScheduleParticleCollisions(const int na, Controller& con)
568  {
569  static const IntVector low(-1, -1, -1);
570  static const IntVector high(1, 1, 1);
571  this->ScheduleParticleCollisions<Controller>(na, con, low, high);
572  }
573 
574  /*
575  * Alright, this seems like it deserves some explanation, as it is somewhat of
576  * a complex design.
577  *
578  * This is to cheat the need for having multiple versions of this function or
579  * having a convoluted data encoding in the parameters/global variables.
580  * Controller is a function object with a function call operator
581  * that acts as a predicate function.
582  *
583  * If the predicate tests true, then the given particle is tested for
584  * collision with the particle designated by <code>na</code>.
585  *
586  * In this sense, the parameter <code>con</code> acts as a closure containing
587  * all the data needed to determine whether or not to use this particle.
588  */
589  template <typename Controller>
590  void Simulation::ScheduleParticleCollisions(
591  const int na, Controller& con,
592  const IntVector& low,
593  const IntVector& high)
594  {
595  assert(na >= 0);
596  assert((unsigned) na < Particles.size());
597 
598  Particle& pa = Particles[na];
599 
600  CellList::NeighborCellIterator it = Partitions.BeginNeighborCell(na, low, high);
601 
602  for (; it.HasNext(); ++it)
603  {
604  if (*it != na && con(*it))
605  {
606  Particle& pb = Particles[*it];
607  pb.UpdateParticle(this->CurrentTime);
608 
609  const double time = ComputeIntersectionTime(pa, pb);
610 
611  if (time != Constants::NEVER)
612  {
613  this->Calendar->ScheduleEvent(
614  this->CurrentTime + time, CollisionEvent, na, *it);
615  }
616  }
617  }
618  }
619 
620  template <typename Writer>
621  void Simulation::Serialize(Writer& writer) const
622  {
623  writer.String("Info") , Info.Serialize(writer);
624  writer.String("RPKEquation") , RPKEquation.Serialize(writer);
625 
626  writer.String("CurrentTime") , writer.Double(CurrentTime);
627  writer.String("TotalCollisions") , writer.UInt64(Stats.TotalCollisions);
628  writer.String("TotalCellCrossings") , writer.UInt64(Stats.TotalCellCrossings);
629  writer.String("TotalWallCollisions") , writer.UInt64(Stats.TotalWallCollisions);
630 
631  writer.String("TotalConeBoundaryCollisions");
632  writer.UInt64(Stats.TotalConeBoundaryCollisions);
633 
634  writer.String("FusionRate"), writer.UInt64(Stats.FusionRate);
635 
636  // Serialize the array of particles to the document
637  writer.String("Particles");
638  writer.StartArray();
639  std::for_each(Particles.begin(), Particles.end(), [&writer](const Particle& p)
640  {
641  p.Serialize(writer);
642  });
643  writer.EndArray();
644  }
645 }
646 
647 #endif /* __SIMULATION_H__ */
unsigned long long TotalCollisions
number of collision events
Definition: Statistics.h:33
bool operator()(const int pa)
Reject only when the the Skip value is given.
Definition: Simulation.h:117
NeighborCellIterator BeginNeighborCell(const int particle, const IntVector &low, const IntVector &high)
Create an iterator into the neighboring cells of a given particle.
Definition: CellListFast.cpp:109
unsigned long long TotalCellCrossings
number of cell crossing events
Definition: Statistics.h:34
This class provides the functionality of a three dimensional cell list.
Definition: CellListFast.h:20
void Serialize(Writer &writer) const
New serialization method that makes use of the ptree library.
Definition: RPK.h:204
unsigned long long TotalConeBoundaryCollisions
number of boundary collisions
Definition: Statistics.h:36
This module defines the RPK class.
Definition: RPK.h:41
EventType
Enumeration of the various event types in the system.
Definition: EventType.h:28
int GetParticleCount() const
Get the current number of particles in the system.
Definition: Simulation.cpp:1013
bool HasRebounded() const
Returns whether or not the bubble wall has rebounded yet.
Definition: Simulation.cpp:910
double GetCurrentTime() const
Definition: Simulation.cpp:978
EventType NextStep()
Advance the simulation by one step.
Definition: Simulation.cpp:915
tvmet::Vector< double, 3UL > DoubleVector
Vector type for representing particle positions and velocities as double precision floating point val...
Definition: Vector.hpp:23
LessThan(const int i)
Build the object with the upper bound.
Definition: Simulation.h:81
Function object to regulate the ScheduleParticleCollisions function.
Definition: Simulation.h:100
AllParticles(const int)
Build the object.
Definition: Simulation.h:54
std::vector< Particle >::const_iterator begin()
Beginning iterator for the particles in the system.
Definition: Simulation.cpp:966
Function object to regulate the ScheduleParticleCollisions function.
Definition: Simulation.h:47
void UpdateParticle(const double currentTime)
Update the particle to the current system time.
Definition: Particle.cpp:33
Definition: Statistics.h:18
DoubleVector Velocity
Velocity of the particle in simulation units.
Definition: Particle.h:26
The Simulation class is the environment in which the simulation occurs.
Definition: Simulation.h:129
const double NEVER
Time value for an event that will never occur.
Definition: Constants.h:35
double FusionRate
number of fusions that have occurred
Definition: Statistics.h:38
unsigned long long GetCollisionCount() const
Get the collision count from the simulation.
Definition: Simulation.cpp:993
unsigned long long GetConeBoundaryCount() const
Get the number of cone boundary events so far.
Definition: Simulation.cpp:1008
std::vector< Particle >::const_iterator end()
Ending iterator used to determine the stopping criteria for the particle iterator.
Definition: Simulation.cpp:972
void PurgeEvents()
Prints all the events in the calendar to standard out if we are in debug mode.
Definition: Simulation.cpp:957
Function object to regulate the ScheduleParticleCollisions function.
Definition: Simulation.h:72
unsigned long long GetWallCollisionCount() const
Get the number of cell wall events so far.
Definition: Simulation.cpp:1003
bool operator()(const int pa)
Test for acceptance.
Definition: Simulation.h:88
Skipping(const int s)
Create the object with the value to skip.
Definition: Simulation.h:110
Defines the structure used to hold the configurable constants of the simulation.
Definition: InfoStruct.h:36
Simulation(const InfoStruct &info, const std::string &outDir="", const bool save=true)
A templatized version of the constructor that takes a particle factory as a type. ...
Definition: Simulation.cpp:843
void Serialize(Writer &writer) const
Serialize the simulation to the writer being given.
Definition: Simulation.h:621
Definition of a basic particle type.
Definition: Particle.h:23
unsigned long long GetCellCrossingCount() const
Get the number of cell crossing events so far.
Definition: Simulation.cpp:998
tvmet::Vector< int, 3UL > IntVector
A vector of integer values to hold a particle&#39;s position in the grid of cells.
Definition: Vector.hpp:29
unsigned long long TotalWallCollisions
number of wall collision events
Definition: Statistics.h:35
bool operator()(const int)
Test true for all given particle indices.
Definition: Simulation.h:61