ParticleHandlerSpeedTest.cpp File Reference

Functions

int main ()
 

Function Documentation

◆ main()

int main ( )
33 {
34  // create a particle handler
35  Mercury3D dpm;
37  SphericalParticle particle(species);
38  CubeInsertionBoundary insertionBoundary;
39  insertionBoundary.set(particle, 1e6, {0, 0, 0}, {10000, 10000, 10000}, {0, 0, 0}, {0, 0, 0});
40  insertionBoundary.setInitialVolume(1e5 * constants::pi / 6.);
41  insertionBoundary.checkBoundaryBeforeTimeStep(&dpm);
42  size_t n = dpm.particleHandler.getSize();
43  logger(INFO, "Number of particles: %", n);
44  logger(INFO, "Size of particles: % bytes, % doubles", sizeof(particle), sizeof(particle) / sizeof(double));
45 
46  // create a data vector
47  std::vector<std::array<double, 82>> dataVector(n);
48  for (int i = 0; i < n; ++i)
49  {
50  dataVector[i][0] = dpm.particleHandler.getObject(i)->getPosition().X;
51  }
52 
53  // create a small data vector
54  std::vector<std::array<double, 8>> smallDataVector(n);
55  for (int i = 0; i < n; ++i)
56  {
57  smallDataVector[i][0] = dpm.particleHandler.getObject(i)->getPosition().X;
58  }
59 
60  // create a particle vector
61  std::vector<SphericalParticle> particleVector(n);
62  for (int i = 0; i < n; ++i) {
63  particleVector[i].setPosition(dpm.particleHandler.getObject(i)->getPosition());
64  }
65 
66  Time timer;
67  double sum=0;
68  int repetitions = 1e8;
69 
70  for (int i = 0; i < repetitions; ++i) {
71  sum += dpm.particleHandler.getObject(rand() % n)->getPosition().X;
72  }
73  double refTime = timer.toctic();
74  logger(INFO, "Time to access randomly data in the particle handler: % s (% pct)", refTime, 100);
75 
76  for (int i = 0; i < repetitions; ++i) {
77  sum += dpm.particleHandler.getObject(i % n)->getPosition().X;
78  }
79  double time = timer.toctic();
80  int relTime = 100. * time / refTime;
81  logger(INFO, "Time to access ordered data in a particle handler: % s (% pct)", time, relTime);
82 
83  for (int i = 0; i < repetitions; ++i) {
84  sum += particleVector[rand() % n].getPosition().X;
85  }
86  time = timer.toctic();
87  relTime = 100. * time / refTime;
88  logger(INFO, "Time to access randomly data in a particle vector: % s (% pct)", time, relTime);
89 
90  for (int i = 0; i < repetitions; ++i) {
91  sum += dataVector[rand() % n][0];
92  }
93  time = timer.toctic();
94  relTime = 100. * time / refTime;
95  logger(INFO, "Time to access randomly data in a vector of arrays: % s (% pct)", time, relTime);
96 
97  for (int i = 0; i < repetitions; ++i) {
98  sum += smallDataVector[rand() % n][0];
99  }
100  time = timer.toctic();
101  relTime = 100. * time / refTime;
102  logger(INFO, "Time to access randomly data in a small vector of small arrays: % s (% pct)", time, relTime);
103 
104  logger(INFO,"Computation: %",sum);
105 
106  logger(INFO,"Conclusions:\n"
107  " - 50\% gain: Ordered data access is much quicker than random\n"
108  " - 20\% gain: Vectors are quicker than handlers\n"
109  " - 0\% gain: Class type (SphericalParticle vs array<double,83>) makes no difference\n"
110  " - 20\% gain: A lean array (8 doubles) is read quicker than a fat array (83 doubles) ");
111 
112 }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:32
Species< LinearViscoelasticNormalSpecies > LinearViscoelasticSpecies
Definition: LinearViscoelasticSpecies.h:33
LL< Log::INFO > INFO
Info log level.
Definition: Logger.cc:55
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
std::enable_if<!std::is_pointer< U >::value, U * >::type copyAndAddObject(const U &object)
Creates a copy of a Object and adds it to the BaseHandler.
Definition: BaseHandler.h:379
unsigned int getSize() const
Gets the size of the particleHandler (including mpi and periodic particles)
Definition: BaseHandler.h:655
T * getObject(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:613
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
Definition: BaseInteractable.h:218
It's an insertion boundary which has cuboidal shape (yes, 'CuboidalInsertionBoundary' would have been...
Definition: CubeInsertionBoundary.h:42
void set(BaseParticle *particleToCopy, unsigned int maxFailed, Vec3D posMin, Vec3D posMax, Vec3D velMin={0, 0, 0}, Vec3D velMax={0, 0, 0})
Sets the properties of the InsertionBoundary for mutliple different particle types.
Definition: CubeInsertionBoundary.cc:107
SpeciesHandler speciesHandler
A handler to that stores the species type i.e. LinearViscoelasticSpecies, etc.
Definition: DPMBase.h:1427
ParticleHandler particleHandler
An object of the class ParticleHandler, contains the pointers to all the particles created.
Definition: DPMBase.h:1437
void checkBoundaryBeforeTimeStep(DPMBase *md) override
Fills the boundary with particles.
Definition: InsertionBoundary.cc:184
void setInitialVolume(Mdouble initialVolume)
Gets the Volume which should be inserted by the insertion routine.
Definition: InsertionBoundary.cc:643
This adds on the hierarchical grid code for 3D problems.
Definition: Mercury3D.h:37
A spherical particle is the most simple particle used in MercuryDPM.
Definition: SphericalParticle.h:37
Allows for timing the algorithms; accurate up to 0.01 sec.
Definition: MercuryTime.h:46
Mdouble toctic()
Outputs the toc value and resets the start time.
Definition: MercuryTime.h:96
Mdouble X
the vector components
Definition: Vector.h:66
const Mdouble pi
Definition: ExtendedMath.h:45
const std::complex< Mdouble > i
Definition: ExtendedMath.h:51

References InsertionBoundary::checkBoundaryBeforeTimeStep(), BaseHandler< T >::copyAndAddObject(), BaseHandler< T >::getObject(), BaseInteractable::getPosition(), BaseHandler< T >::getSize(), constants::i, INFO, logger, n, DPMBase::particleHandler, constants::pi, CubeInsertionBoundary::set(), InsertionBoundary::setInitialVolume(), DPMBase::speciesHandler, Time::toctic(), and Vec3D::X.