Skip to content

Commit 04b1b69

Browse files
committed
reserve refinement
1 parent fffd323 commit 04b1b69

File tree

5 files changed

+82
-50
lines changed

5 files changed

+82
-50
lines changed

.github/workflows/cmake_ubuntu.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,11 @@ jobs:
7878
make -j2 && sudo make install && cd ../.. && rm -rf samrai
7979
cd ${{runner.workspace}}/build && rm -rf *
8080
cmake $GITHUB_WORKSPACE -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON --fresh \
81-
-DCMAKE_BUILD_TYPE=RelWithDebInfo -Dasan=OFF \
81+
-DCMAKE_BUILD_TYPE=Debug -Dasan=OFF \
8282
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
8383
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
8484
-DlowResourceTests=ON -DdevMode=ON -Dbench=ON \
85-
-DCMAKE_CXX_FLAGS="-DPHARE_DIAG_DOUBLES=1 " -Dphare_configurator=ON
85+
-DCMAKE_CXX_FLAGS="-O3 -DPHARE_DIAG_DOUBLES=1 " -Dphare_configurator=ON
8686
8787
- name: Build
8888
working-directory: ${{runner.workspace}}/build

src/amr/data/field/refine/electric_field_refiner.hpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44

55
#include "core/def/phare_mpi.hpp"
66

7-
#include <SAMRAI/hier/Box.h>
8-
7+
#include "amr/amr_constants.hpp"
98
#include "amr/resources_manager/amr_utils.hpp"
9+
1010
#include "core/utilities/constants.hpp"
1111
#include "core/data/grid/gridlayoutdefs.hpp"
1212
#include "core/utilities/point/point.hpp"
1313

14+
#include <SAMRAI/hier/Box.h>
15+
1416
#include <cstddef>
1517

1618
namespace PHARE::amr
@@ -43,8 +45,8 @@ class ElectricFieldRefiner
4345
{
4446
TBOX_ASSERT(coarseField.physicalQuantity() == fineField.physicalQuantity());
4547

46-
auto const locFineIdx = AMRToLocal(fineIndex, fineBox_);
47-
auto constexpr refinementRatio = 2;
48+
auto const locFineIdx = AMRToLocal(fineIndex, fineBox_);
49+
4850
auto coarseIdx{fineIndex};
4951
for (auto& idx : coarseIdx)
5052
idx = idx / refinementRatio;

src/amr/data/particles/refine/particles_data_split.hpp

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,22 @@
22
#define PHARE_PARTICLES_DATA_SPLIT_HPP
33

44

5+
#include "core/def.hpp"
6+
#include "phare_core.hpp"
57
#include "core/def/phare_mpi.hpp"
8+
#include "core/utilities/constants.hpp"
69

7-
#include "core/def.hpp"
8-
#include "amr/data/particles/particles_data.hpp"
9-
#include "amr/resources_manager/amr_utils.hpp"
1010
#include "split.hpp"
11-
#include "core/utilities/constants.hpp"
12-
#include "phare_core.hpp"
1311
#include "amr/amr_constants.hpp"
12+
#include "amr/utilities/box/amr_box.hpp"
13+
#include "amr/resources_manager/amr_utils.hpp"
14+
#include "amr/data/particles/particles_data.hpp"
1415

1516
#include <SAMRAI/geom/CartesianPatchGeometry.h>
1617
#include <SAMRAI/hier/Box.h>
1718
#include <SAMRAI/hier/RefineOperator.h>
1819
#include <SAMRAI/pdat/CellOverlap.h>
1920

20-
#include <functional>
2121

2222

2323
namespace PHARE
@@ -53,6 +53,12 @@ namespace amr
5353
template<typename ParticleArray, ParticlesDataSplitType splitType, typename Splitter>
5454
class ParticlesRefineOperator : public SAMRAI::hier::RefineOperator
5555
{
56+
using Particle_t = typename ParticleArray::value_type;
57+
static constexpr bool putParticlesInCoarseBoundary
58+
= splitType == ParticlesDataSplitType::coarseBoundary
59+
|| splitType == ParticlesDataSplitType::coarseBoundaryOld
60+
|| splitType == ParticlesDataSplitType::coarseBoundaryNew;
61+
5662
public:
5763
static constexpr auto dim = Splitter::dimension;
5864
static constexpr auto interpOrder = Splitter::interp_order;
@@ -99,7 +105,7 @@ namespace amr
99105
= std::dynamic_pointer_cast<ParticlesData<ParticleArray>>(
100106
source.getPatchData(sourceComponent));
101107

102-
// Finnaly we need the cartesion geometry of both patch.
108+
// Finaly we need the cartesion geometry of both patch.
103109
auto patchGeomDestination
104110
= std::dynamic_pointer_cast<SAMRAI::geom::CartesianPatchGeometry>(
105111
destination.getPatchGeometry());
@@ -133,9 +139,15 @@ namespace amr
133139
}
134140
}
135141

142+
template<typename Fn>
143+
static void _reserve(ParticleArray& particles, Fn&& counter)
144+
{ // only reserve for regular refinement of domain to start with
145+
if constexpr (!putParticlesInCoarseBoundary)
146+
particles.reserve(counter() * nbRefinedPart);
147+
}
136148

137149
/** @brief given two ParticlesData (destination and source),
138-
* an overlap , a ratio and the geometry of both patches, perform the
150+
* an overlap, a ratio and the geometry of both patches, perform the
139151
* splitting of coarse particles onto the destination patch
140152
*/
141153
void refine_(ParticlesData<ParticleArray>& destParticlesData,
@@ -166,43 +178,47 @@ namespace amr
166178
// same for destinationGhostBox and destinationDomainBox the later will allow to get an
167179
// index relative to the interior
168180

181+
std::array const particlesArrays{&srcInteriorParticles, &srcGhostParticles};
182+
183+
auto const count_expected = [&]() {
184+
std::size_t incoming_estimate = 0;
185+
for (auto const& destinationBox : destBoxes)
186+
{
187+
auto const coarseSplitBox
188+
= coarsen(phare_box_from<dim>(getSplitBox(destinationBox)));
189+
for (auto const& sourceParticlesArray : particlesArrays)
190+
incoming_estimate += sourceParticlesArray->nbr_particles_in(coarseSplitBox);
191+
}
192+
return incoming_estimate;
193+
};
194+
_reserve(destDomainParticles, count_expected);
195+
169196
Splitter split;
170197

171198
// The PatchLevelFillPattern had compute boxes that correspond to the expected filling.
172199
// In case of a coarseBoundary it will most likely give multiple boxes
173200
// in case of interior, this will be just one box usually
174201
for (auto const& destinationBox : destBoxes)
175202
{
176-
std::array particlesArrays{&srcInteriorParticles, &srcGhostParticles};
177-
auto splitBox = getSplitBox(destinationBox);
203+
auto const splitBox = getSplitBox(destinationBox);
178204

179-
auto isInDest = [&destinationBox](auto const& particle) //
205+
auto const isInDest = [&destinationBox](auto const& particle) //
180206
{ return isInBox(destinationBox, particle); };
181207

182-
183208
for (auto const& sourceParticlesArray : particlesArrays)
184209
{
185210
for (auto const& particle : *sourceParticlesArray)
186211
{
187-
std::array<typename ParticleArray::value_type, nbRefinedPart>
188-
refinedParticles;
189-
auto particleRefinedPos = toFineGrid<interpOrder>(particle);
212+
auto const particleRefinedPos = toFineGrid<interpOrder>(particle);
190213

191214
if (isInBox(splitBox, particleRefinedPos))
192215
{
216+
std::array<Particle_t, nbRefinedPart> refinedParticles;
193217
split(particleRefinedPos, refinedParticles);
194218

195-
196219
// we need to know in which of interior or levelGhostParticlesXXXX
197220
// arrays we must put particles
198221

199-
bool constexpr putParticlesInCoarseBoundary
200-
= splitType == ParticlesDataSplitType::coarseBoundary
201-
|| splitType == ParticlesDataSplitType::coarseBoundaryOld
202-
|| splitType == ParticlesDataSplitType::coarseBoundaryNew;
203-
204-
205-
206222
if constexpr (putParticlesInCoarseBoundary)
207223
{
208224
if constexpr (splitType == ParticlesDataSplitType::coarseBoundary)
@@ -243,9 +259,9 @@ namespace amr
243259
std::back_inserter(destDomainParticles), isInDest);
244260
}
245261
} // end is candidate for split
246-
} // end loop on particles
247-
} // end loop on source particle arrays
248-
} // loop on destination box
262+
} // end loop on particles
263+
} // end loop on source particle arrays
264+
} // loop on destination box
249265
}
250266

251267

src/amr/utilities/box/amr_box.hpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
#define PHARE_AMR_UTILITIES_BOX_BOX_HPP
33

44

5+
#include "core/def.hpp"
56
#include "core/def/phare_mpi.hpp"
7+
#include "core/utilities/box/box.hpp"
68

9+
#include "amr/amr_constants.hpp"
710

811
#include "SAMRAI/hier/Box.h"
9-
#include "core/utilities/box/box.hpp"
10-
#include "core/def.hpp"
11-
1212

1313
namespace PHARE::amr
1414
{
@@ -85,6 +85,22 @@ struct Box : public PHARE::core::Box<Type, dim>
8585
}
8686
};
8787

88+
template<std::size_t dim>
89+
auto refine(core::Box<int, dim> box)
90+
{
91+
for (std::uint8_t di = 0; di < dim; ++di)
92+
box.lower[di] *= refinementRatio, box.upper[di] *= refinementRatio;
93+
return box;
94+
}
95+
template<std::size_t dim>
96+
auto coarsen(core::Box<int, dim> box)
97+
{
98+
for (std::uint8_t di = 0; di < dim; ++di)
99+
box.lower[di] /= refinementRatio, box.upper[di] /= refinementRatio;
100+
101+
return box;
102+
}
103+
88104
} // namespace PHARE::amr
89105

90106
#endif

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

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class MaxwellianParticleInitializer : public ParticleInitializer<ParticleArray,
4444
std::uint32_t const& nbrParticlesPerCell, std::optional<std::size_t> seed = {},
4545
Basis const basis = Basis::Cartesian,
4646
std::array<InputFunction, 3> const& magneticField = {nullptr, nullptr, nullptr},
47-
double densityCutOff = 1e-5)
47+
double const densityCutOff = 1e-5, double const over_alloc_factor = .1)
4848
: density_{density}
4949
, bulkVelocity_{bulkVelocity}
5050
, thermalVelocity_{thermalVelocity}
@@ -54,6 +54,7 @@ class MaxwellianParticleInitializer : public ParticleInitializer<ParticleArray,
5454
, nbrParticlePerCell_{nbrParticlesPerCell}
5555
, basis_{basis}
5656
, rngSeed_{seed}
57+
, over_alloc_factor_{over_alloc_factor}
5758
{
5859
}
5960

@@ -92,6 +93,7 @@ class MaxwellianParticleInitializer : public ParticleInitializer<ParticleArray,
9293
std::uint32_t nbrParticlePerCell_;
9394
Basis basis_;
9495
std::optional<std::size_t> rngSeed_;
96+
double over_alloc_factor_ = .1;
9597
};
9698

9799

@@ -178,20 +180,16 @@ void MaxwellianParticleInitializer<ParticleArray, GridLayout>::loadParticles(
178180
auto randGen = getRNG(rngSeed_);
179181
ParticleDeltaDistribution<double> deltaDistrib;
180182

181-
std::size_t const expected_size
182-
= [&](auto const& _n /* or error: reference to local binding 'n' declared*/) {
183-
std::size_t size = 0;
184-
for (std::size_t flatCellIdx = 0; flatCellIdx < ndCellIndices.size(); ++flatCellIdx)
185-
if (_n[flatCellIdx] >= densityCutOff_)
186-
++size;
187-
return size * nbrParticlePerCell_;
188-
}(n);
189-
190-
double const over_alloc_factor = .1; // todo from dict
191-
std::size_t const allocate_size
192-
= expected_size
193-
+ (layout.AMRBox().surface_cell_count() * (nbrParticlePerCell_ * over_alloc_factor));
194-
particles.reserve(allocate_size);
183+
auto const expected_size = std::accumulate(n, n + ndCellIndices.size(), std::size_t{0},
184+
[&](auto const& sum, auto const& density_value) {
185+
return (density_value > densityCutOff_)
186+
? sum + nbrParticlePerCell_
187+
: sum;
188+
});
189+
190+
auto const incoming_estimate
191+
= (layout.AMRBox().surface_cell_count() * (nbrParticlePerCell_ * over_alloc_factor_));
192+
particles.reserve(expected_size + incoming_estimate);
195193

196194
for (std::size_t flatCellIdx = 0; flatCellIdx < ndCellIndices.size(); ++flatCellIdx)
197195
{

0 commit comments

Comments
 (0)