Skip to content

Commit 03b725b

Browse files
committed
minimize maxwellian vector capacity somewhat
1 parent ecef2fe commit 03b725b

File tree

4 files changed

+85
-19
lines changed

4 files changed

+85
-19
lines changed

src/core/data/ions/particle_initializers/maxwellian_particle_initializer.hpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,20 @@ void MaxwellianParticleInitializer<ParticleArray, GridLayout>::loadParticles(
178178
auto randGen = getRNG(rngSeed_);
179179
ParticleDeltaDistribution<double> deltaDistrib;
180180

181+
std::size_t const expected_size = [&]() {
182+
std::size_t size = 0;
183+
for (std::size_t flatCellIdx = 0; flatCellIdx < ndCellIndices.size(); ++flatCellIdx)
184+
if (n[flatCellIdx] >= densityCutOff_)
185+
++size;
186+
return size * nbrParticlePerCell_;
187+
}();
188+
189+
double const over_alloc_factor = .1; // todo from dict
190+
std::size_t const allocate_size
191+
= expected_size
192+
+ (layout.AMRBox().surface_cell_count() * (nbrParticlePerCell_ * over_alloc_factor));
193+
particles.reserve(allocate_size);
194+
181195
for (std::size_t flatCellIdx = 0; flatCellIdx < ndCellIndices.size(); ++flatCellIdx)
182196
{
183197
if (n[flatCellIdx] < densityCutOff_)

src/core/data/particles/particle.hpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ NO_DISCARD auto cellAsPoint(Particle const& particle)
3939
template<size_t dim>
4040
struct Particle
4141
{
42+
std::array<std::uint8_t, 3> constexpr static sizes = {52, 64, 76};
4243
static_assert(dim > 0 and dim < 4, "Only dimensions 1,2,3 are supported.");
4344
static const size_t dimension = dim;
4445

@@ -54,12 +55,11 @@ struct Particle
5455

5556
Particle() = default;
5657

57-
double weight = 0;
58-
double charge = 0;
59-
60-
std::array<int, dim> iCell = ConstArray<int, dim>();
61-
std::array<double, dim> delta = ConstArray<double, dim>();
62-
std::array<double, 3> v = ConstArray<double, 3>();
58+
double weight = 0; // 8
59+
double charge = 0; // 8
60+
std::array<int, dim> iCell = ConstArray<int, dim>(); // 4 * dim
61+
std::array<double, dim> delta = ConstArray<double, dim>(); // 8 * dim
62+
std::array<double, 3> v = ConstArray<double, 3>(); // 8 * 3
6363

6464
NO_DISCARD bool operator==(Particle<dim> const& that) const
6565
{
@@ -121,9 +121,9 @@ inline constexpr auto is_phare_particle_type
121121

122122
template<std::size_t dim, template<std::size_t> typename ParticleA,
123123
template<std::size_t> typename ParticleB>
124-
NO_DISCARD typename std::enable_if_t<
125-
is_phare_particle_type<dim, ParticleA<dim>> and is_phare_particle_type<dim, ParticleB<dim>>,
126-
bool>
124+
NO_DISCARD typename std::enable_if_t<is_phare_particle_type<dim, ParticleA<dim>>
125+
and is_phare_particle_type<dim, ParticleB<dim>>,
126+
bool>
127127
operator==(ParticleA<dim> const& particleA, ParticleB<dim> const& particleB)
128128
{
129129
return particleA.weight == particleB.weight and //

src/core/utilities/box/box.hpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ template<typename Type, std::size_t dim>
2626
struct Box
2727
{
2828
static const size_t dimension = dim;
29-
29+
using value_type = Type;
3030

3131
Point<Type, dim> lower;
3232
Point<Type, dim> upper;
@@ -130,9 +130,16 @@ struct Box
130130
return iterator{this, {upper[0] + 1, upper[1] + 1, upper[2] + 1}};
131131
}
132132
}
133-
using value_type = Type;
134133

135134

135+
NO_DISCARD auto surface_cell_count() const
136+
{
137+
// assumes box never smaller than 3 in any direction
138+
auto const shape_ = shape();
139+
auto const nested = shape_ - 2;
140+
return core::product(shape_) - core::product(nested);
141+
}
142+
136143
NO_DISCARD constexpr static std::size_t nbrRemainBoxes()
137144
{
138145
if constexpr (dim == 1)

tests/core/data/maxwellian_particle_initializer/test_maxwellian_particle_initializer.cpp

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,23 @@
99
#include "core/utilities/box/box.hpp"
1010
#include "core/utilities/point/point.hpp"
1111

12-
#include "gmock/gmock.h"
1312
#include "gtest/gtest.h"
1413

1514
#include "tests/initializer/init_functions.hpp"
16-
using namespace PHARE::initializer::test_fn::func_1d; // density/etc are here
15+
#include "tests/core/data/gridlayout/test_gridlayout.hpp"
1716

1817
using namespace PHARE::core;
19-
using namespace PHARE::initializer;
18+
19+
namespace PHARE::initializer::test_fn::func_1d
20+
{
2021

2122

2223
class AMaxwellianParticleInitializer1D : public ::testing::Test
2324
{
2425
private:
25-
using GridLayoutT = GridLayout<GridLayoutImplYee<1, 1>>;
2626
using ParticleArrayT = ParticleArray<1>;
2727
using InitFunctionArray = std::array<InitFunction<1>, 3>;
28+
using GridLayoutT = GridLayout<GridLayoutImplYee<1, 1>>;
2829

2930
public:
3031
AMaxwellianParticleInitializer1D()
@@ -34,10 +35,8 @@ class AMaxwellianParticleInitializer1D : public ::testing::Test
3435
density, InitFunctionArray{vx, vy, vz}, InitFunctionArray{vthx, vthy, vthz}, 1.,
3536
nbrParticlesPerCell)}
3637
{
37-
//
3838
}
3939

40-
4140
GridLayoutT layout;
4241
ParticleArrayT particles;
4342
std::uint32_t nbrParticlesPerCell{10000};
@@ -46,7 +45,6 @@ class AMaxwellianParticleInitializer1D : public ::testing::Test
4645

4746

4847

49-
5048
TEST_F(AMaxwellianParticleInitializer1D, loadsTheCorrectNbrOfParticles)
5149
{
5250
auto nbrCells = layout.nbrCells();
@@ -57,7 +55,6 @@ TEST_F(AMaxwellianParticleInitializer1D, loadsTheCorrectNbrOfParticles)
5755

5856

5957

60-
6158
TEST_F(AMaxwellianParticleInitializer1D, loadsParticlesInTheDomain)
6259
{
6360
initializer->loadParticles(particles, layout);
@@ -73,8 +70,56 @@ TEST_F(AMaxwellianParticleInitializer1D, loadsParticlesInTheDomain)
7370
}
7471
}
7572

73+
} // namespace PHARE::initializer::test_fn::func_1d
74+
75+
76+
namespace PHARE::initializer::test_fn::func_2d
77+
{
78+
79+
class AMaxwellianParticleInitializer2D : public ::testing::Test
80+
{
81+
private:
82+
using ParticleArrayT = ParticleArray<2>;
83+
using InitFunctionArray = std::array<InitFunction<2>, 3>;
84+
using GridLayoutT = GridLayout<GridLayoutImplYee<2, 1>>;
85+
86+
87+
88+
public:
89+
AMaxwellianParticleInitializer2D()
90+
: layout{50}
91+
, initializer{std::make_unique<MaxwellianParticleInitializer<ParticleArrayT, GridLayoutT>>(
92+
density, InitFunctionArray{vx, vy, vz}, InitFunctionArray{vthx, vthy, vthz}, 1.,
93+
nbrParticlesPerCell)}
94+
{
95+
}
96+
97+
TestGridLayout<GridLayoutT> layout;
98+
ParticleArrayT particles{layout.AMRBox()};
99+
std::uint32_t nbrParticlesPerCell{600};
100+
std::unique_ptr<MaxwellianParticleInitializer<ParticleArrayT, GridLayoutT>> initializer;
101+
};
102+
103+
TEST_F(AMaxwellianParticleInitializer2D, loadsTheCorrectNbrOfParticles)
104+
{
105+
// vector push back allocation observations
106+
// 100 ppc = 262144 - 250000 = 12144 == 12144 * 64 / 1e6 == .7MB overallocated
107+
// 600 ppc = 2097152 - 1500000 = 597152 * 64 / 1e6 == 38MB overallocated
108+
109+
auto const expectedNbrParticles = nbrParticlesPerCell * product(layout.AMRBox().shape());
110+
initializer->loadParticles(particles, layout);
111+
EXPECT_EQ(expectedNbrParticles, particles.size());
112+
auto outer_cell_count = std::pow(50, 2) - std::pow(48, 2);
113+
EXPECT_EQ(particles.capacity(),
114+
particles.size() + (outer_cell_count * nbrParticlesPerCell * .1));
115+
116+
// new method
117+
// 100 ppc = (1511760 - 1500000) * 64 / 1e6 == 0.12544 overallocated
118+
// 600 ppc = (1511760 - 1500000) * 64 / 1e6 == 0.75264 overallocated
119+
}
76120

77121

122+
} // namespace PHARE::initializer::test_fn::func_2d
78123

79124
int main(int argc, char** argv)
80125
{

0 commit comments

Comments
 (0)