Skip to content

Commit

Permalink
outp/hdf5: add template argument for particle selector
Browse files Browse the repository at this point in the history
This particle selector decides whether to include a given particle in the
output. Other than the trivial ParticleSelectorAll,
ParticleSelectorEveryNth<N> is provided ot select every nth particle.
  • Loading branch information
germasch committed Aug 29, 2024
1 parent 3a23a9a commit 0b4606f
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 13 deletions.
44 changes: 39 additions & 5 deletions src/libpsc/psc_output_particles/output_particles_hdf5_impl.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,38 @@ private:
Hdf5ParticleType prt_type_;
};

template <int EVERY>
class ParticleSelectorEveryNth
{
public:
template <typename Particle>
bool operator()(const Particle& prt)
{
// return true for every `every_`th particle
return (cnt_++ % EVERY) == 0;
}

private:
int cnt_ = 0;
};

class ParticleSelectorAll
{
public:
template <typename Particle>
bool operator()(const Particle& prt)
{
return true;
}
};

namespace detail
{

// ======================================================================
// OutputParticlesHdf5

template <typename Mparticles>
template <typename Mparticles, typename ParticleSelector>
struct OutputParticlesHdf5
{
using writer_type = OutputParticlesWriterHDF5;
Expand Down Expand Up @@ -353,17 +378,24 @@ struct OutputParticlesHdf5
{
int nr_kinds = mprts.grid().kinds.size();

ParticleSelector selector;

for (int p = 0; p < mprts.n_patches(); p++) {
const int* ldims = mprts.grid().ldims;
int nr_indices = ldims[0] * ldims[1] * ldims[2] * nr_kinds;
off[p].resize(nr_indices + 1);
auto&& prts = mprts[p];
unsigned int n_prts = prts.size();
std::vector<int> particle_indices;
particle_indices.reserve(n_prts);

// counting sort to get map
for (int n = 0; n < n_prts; n++) {
int si = get_sort_index(prts, n);
off[p][si]++;
if (selector(prts[n])) {
particle_indices.push_back(n);
int si = get_sort_index(prts, n);
off[p][si]++;
}
}
// prefix sum to get offsets
int o = 0;
Expand All @@ -377,7 +409,7 @@ struct OutputParticlesHdf5

// sort a map only, not the actual particles
map[p].resize(n_prts);
for (int n = 0; n < n_prts; n++) {
for (auto n : particle_indices) {
int si = get_sort_index(prts, n);
map[p][off2[si]++] = n;
}
Expand Down Expand Up @@ -609,6 +641,7 @@ private:

} // namespace detail

template <typename ParticleSelector = ParticleSelectorAll>
class OutputParticlesHdf5 : OutputParticlesBase
{
static OutputParticlesParams adjust_params(
Expand Down Expand Up @@ -640,7 +673,8 @@ public:
return;
}

detail::OutputParticlesHdf5<Mparticles> impl{grid, params_};
detail::OutputParticlesHdf5<Mparticles, ParticleSelector> impl{grid,
params_};
impl(mprts, writer_);
}

Expand Down
12 changes: 6 additions & 6 deletions src/libpsc/tests/test_output_particles.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,14 @@ struct OutputParticlesTest : ::testing::Test
Int3 ibn = {2, 2, 2};
};

using OutputParticlesTestTypes =
::testing::Types<Config<dim_xyz, MparticlesSingle, OutputParticlesAscii>
using OutputParticlesTestTypes = ::testing::Types<
Config<dim_xyz, MparticlesSingle, OutputParticlesAscii>
#ifdef H5_HAVE_PARALLEL
,
Config<dim_xyz, MparticlesSingle, OutputParticlesHdf5>,
Config<dim_xyz, MparticlesDouble, OutputParticlesHdf5>
,
Config<dim_xyz, MparticlesSingle, OutputParticlesHdf5<ParticleSelectorAll>>,
Config<dim_xyz, MparticlesDouble, OutputParticlesHdf5<ParticleSelectorAll>>
#endif
>;
>;

TYPED_TEST_SUITE(OutputParticlesTest, OutputParticlesTestTypes);

Expand Down
4 changes: 2 additions & 2 deletions src/psc_config.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

#include "../libpsc/vpic/fields_item_vpic.hxx"

using OutputParticlesDefault = OutputParticlesHdf5;
using OutputParticlesDefault = OutputParticlesHdf5<ParticleSelectorAll>;

struct SimulationNone
{
Expand Down Expand Up @@ -252,7 +252,7 @@ struct PscConfigVpicPsc
using BndParticles = BndParticlesVpic<Mparticles>;
using Checks = ChecksVpic<Mparticles, MfieldsState>;
using Marder = MarderVpic<Mparticles, MfieldsState>;
using OutputParticles = OutputParticlesHdf5;
using OutputParticles = OutputParticlesHdf5<ParticleSelectorAll>;
using OutputHydro = OutputHydroQ<Mparticles, MfieldsHydro,
typename VpicConfig::MfieldsInterpolator>;
using Dim = dim_xz;
Expand Down
4 changes: 4 additions & 0 deletions src/psc_flatfoil_yz.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,11 @@ using Balance = PscConfig::Balance;
using Collision = PscConfig::Collision;
using Checks = PscConfig::Checks;
using Marder = PscConfig::Marder;
#if CASE == CASE_2D_SMALL
using OutputParticles = OutputParticlesHdf5<ParticleSelectorEveryNth<10>>;
#else
using OutputParticles = PscConfig::OutputParticles;
#endif
using Moment_n = typename Moment_n_Selector<Mparticles, Dim>::type;
using Heating = typename HeatingSelector<Mparticles>::Heating;

Expand Down

0 comments on commit 0b4606f

Please sign in to comment.