ParticleHandlerSpeedTest.cpp File Reference

Functions

int main ()
 

Function Documentation

◆ main()

int main ( )
12 {
13  // create a particle handler
14  Mercury3D dpm;
16  SphericalParticle particle(species);
17  CubeInsertionBoundary insertionBoundary;
18  insertionBoundary.set(particle, 1e6, {0, 0, 0}, {10000, 10000, 10000}, {0, 0, 0}, {0, 0, 0});
19  insertionBoundary.setInitialVolume(1e5 * constants::pi / 6.);
20  insertionBoundary.checkBoundaryBeforeTimeStep(&dpm);
21  size_t n = dpm.particleHandler.getSize();
22  logger(INFO, "Number of particles: %", n);
23  logger(INFO, "Size of particles: % bytes, % doubles", sizeof(particle), sizeof(particle) / sizeof(double));
24 
25  // create a data vector
26  std::vector<std::array<double, 82>> dataVector(n);
27  for (int i = 0; i < n; ++i)
28  {
29  dataVector[i][0] = dpm.particleHandler.getObject(i)->getPosition().X;
30  }
31 
32  // create a small data vector
33  std::vector<std::array<double, 8>> smallDataVector(n);
34  for (int i = 0; i < n; ++i)
35  {
36  smallDataVector[i][0] = dpm.particleHandler.getObject(i)->getPosition().X;
37  }
38 
39  // create a particle vector
40  std::vector<SphericalParticle> particleVector(n);
41  for (int i = 0; i < n; ++i) {
42  particleVector[i].setPosition(dpm.particleHandler.getObject(i)->getPosition());
43  }
44 
45  Time timer;
46  double sum=0;
47  int repetitions = 1e8;
48 
49  for (int i = 0; i < repetitions; ++i) {
50  sum += dpm.particleHandler.getObject(rand() % n)->getPosition().X;
51  }
52  double refTime = timer.toctic();
53  logger(INFO, "Time to access randomly data in the particle handler: % s (% pct)", refTime, 100);
54 
55  for (int i = 0; i < repetitions; ++i) {
56  sum += dpm.particleHandler.getObject(i % n)->getPosition().X;
57  }
58  double time = timer.toctic();
59  int relTime = 100. * time / refTime;
60  logger(INFO, "Time to access ordered data in a particle handler: % s (% pct)", time, relTime);
61 
62  for (int i = 0; i < repetitions; ++i) {
63  sum += particleVector[rand() % n].getPosition().X;
64  }
65  time = timer.toctic();
66  relTime = 100. * time / refTime;
67  logger(INFO, "Time to access randomly data in a particle vector: % s (% pct)", time, relTime);
68 
69  for (int i = 0; i < repetitions; ++i) {
70  sum += dataVector[rand() % n][0];
71  }
72  time = timer.toctic();
73  relTime = 100. * time / refTime;
74  logger(INFO, "Time to access randomly data in a vector of arrays: % s (% pct)", time, relTime);
75 
76  for (int i = 0; i < repetitions; ++i) {
77  sum += smallDataVector[rand() % n][0];
78  }
79  time = timer.toctic();
80  relTime = 100. * time / refTime;
81  logger(INFO, "Time to access randomly data in a small vector of small arrays: % s (% pct)", time, relTime);
82 
83  logger(INFO,"Computation: %",sum);
84 
85  logger(INFO,"Conclusions:\n"
86  " - 50\% gain: Ordered data access is much quicker than random\n"
87  " - 20\% gain: Vectors are quicker than handlers\n"
88  " - 0\% gain: Class type (SphericalParticle vs array<double,83>) makes no difference\n"
89  " - 20\% gain: A lean array (8 doubles) is read quicker than a fat array (83 doubles) ");
90 
91 }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Species< LinearViscoelasticNormalSpecies > LinearViscoelasticSpecies
Definition: LinearViscoelasticSpecies.h:11
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:360
unsigned int getSize() const
Gets the size of the particleHandler (including mpi and periodic particles)
Definition: BaseHandler.h:663
T * getObject(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:621
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
Definition: BaseInteractable.h:197
It's an insertion boundary which has cuboidal shape (yes, 'CuboidalInsertionBoundary' would have been...
Definition: CubeInsertionBoundary.h:21
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:86
SpeciesHandler speciesHandler
A handler to that stores the species type i.e. LinearViscoelasticSpecies, etc.
Definition: DPMBase.h:1433
ParticleHandler particleHandler
An object of the class ParticleHandler, contains the pointers to all the particles created.
Definition: DPMBase.h:1443
void checkBoundaryBeforeTimeStep(DPMBase *md) override
Fills the boundary with particles.
Definition: InsertionBoundary.cc:163
void setInitialVolume(Mdouble initialVolume)
Gets the Volume which should be inserted by the insertion routine.
Definition: InsertionBoundary.cc:620
This adds on the hierarchical grid code for 3D problems.
Definition: Mercury3D.h:16
A spherical particle is the most simple particle used in MercuryDPM.
Definition: SphericalParticle.h:16
Allows for timing the algorithms; accurate up to 0.01 sec.
Definition: MercuryTime.h:25
Mdouble X
the vector components
Definition: Kernel/Math/Vector.h:45
#define INFO(i)
Definition: mumps_solver.h:54
const Mdouble pi
Definition: ExtendedMath.h:23
double timer
Definition: oomph_metis_from_parmetis_3.1.1/struct.h:210

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