116#ifndef CD_PARTICLESOA_H
117#define CD_PARTICLESOA_H
128#include <type_traits>
141#include <CD_NamespaceHeader.H>
149#ifndef CD_PARTICLE_REAL
150#define CD_PARTICLE_REAL double
248template <
typename...
Ms>
280template <
typename... Ms>
301 static constexpr auto columns = std::make_tuple();
318template <
typename C,
typename T>
337template <
typename A,
typename B>
355 return a_lhs == a_rhs;
364template <
typename Tup,
typename M>
368 return std::tuple_size<Tup>::value;
381template <
typename Tup,
typename M, std::size_t I, std::size_t... Rest>
383indexOfImpl(
const Tup& a_t, M a_target, std::index_sequence<I, Rest...>)
noexcept
385 return eqMember(std::get<I>(a_t), a_target) ? I :
indexOfImpl(a_t, a_target, std::index_sequence<Rest...>{});
396template <
typename Tup,
typename M>
400 return indexOfImpl(a_t, a_target, std::make_index_sequence<std::tuple_size<Tup>::value>{});
408template <
typename T, std::
size_t N>
414 template <std::
size_t>
422 template <std::size_t... I>
423 static std::tuple<Always<I>...>
make(std::index_sequence<I...>);
428 using Type =
decltype(
make(std::make_index_sequence<N>{}));
435template <
typename Tuple>
442template <
typename... Ms>
448 using Type = std::tuple<typename MemberPointerTraits<Ms>::ValueType...>;
468template <
typename... Rest>
470sumSizes(std::size_t a_first, Rest... a_rest)
noexcept
472 return a_first +
sumSizes(a_rest...);
479template <
typename Tuple>
486template <
typename... Ts>
492 static constexpr std::size_t s_value =
sumSizes(
sizeof(Ts)...);
499template <
typename Tuple>
506template <
typename... Ts>
512 static constexpr bool s_value = (std::is_trivially_copyable<Ts>::value && ...);
519template <
typename...>
531template <
typename... Ts>
542template <
typename Traits, std::size_t... I>
543constexpr std::index_sequence<indexOf(Traits::columns, std::get<I>(Traits::h5Columns))...>
544deriveH5Seq([[maybe_unused]] std::index_sequence<I...> a_seq)
noexcept
555template <
typename Traits,
typename Fallback,
typename =
void>
569template <
typename Traits,
typename Fallback>
575 using H5Tuple = std::remove_cv_t<std::remove_reference_t<
decltype(Traits::h5Columns)>>;
579 using Type =
decltype(deriveH5Seq<Traits>(std::make_index_sequence<std::tuple_size<H5Tuple>::value>{}));
590pushBytes(
unsigned char*& a_buf,
const T& a_value)
noexcept
592 static_assert(std::is_trivially_copyable<T>::value,
"SoA columns must be trivially copyable");
593 std::memcpy(a_buf, &a_value,
sizeof(T));
605pullBytes(
const unsigned char*& a_buf, T& a_value)
noexcept
607 static_assert(std::is_trivially_copyable<T>::value,
"SoA columns must be trivially copyable");
608 std::memcpy(&a_value, a_buf,
sizeof(T));
653template <
typename P = NoPayload,
typename Traits = ParticleTraits<P>>
665 using PayloadColumns = std::remove_cv_t<std::remove_reference_t<
decltype(Traits::columns)>>;
680 static constexpr std::size_t
s_idCol = SpaceDim + 1;
718 using MandatoryValues =
decltype(std::tuple_cat(std::declval<PositionValues>(),
719 std::declval<std::tuple<double, ParticleID, RankID, GhostType>>()));
735 using ColumnValueTuple =
decltype(std::tuple_cat(std::declval<MandatoryValues>(), std::declval<PayloadValues>()));
740 template <std::
size_t K>
741 using ColumnType = std::tuple_element_t<K, ColumnValueTuple>;
749 template <
typename M>
750 static constexpr std::size_t
753 return s_payloadBegin + detail::indexOf(Traits::columns, a_member);
764 static_assert(std::is_default_constructible<P>::value,
"payload type P must be default-constructible");
766 "every particle column must be trivially copyable for MPI/HDF5");
806 this->
steal(a_other);
817 if (
this != &a_other) {
821 this->
steal(a_other);
858 std::swap(
m_buffer, a_other.m_buffer);
859 std::swap(
m_bytes, a_other.m_bytes);
861 std::swap(
m_size, a_other.m_size);
862 std::swap(
m_sorted, a_other.m_sorted);
866 std::swap(
m_sortDx, a_other.m_sortDx);
922 reserve(
const std::size_t a_capacity);
929 resize(
const std::size_t a_count);
955 append(
const RealVect& a_position,
const double a_weight)
957 this->
append(a_position, a_weight, P{});
969 append(
const RealVect& a_position,
const double a_weight,
const P& a_payload);
1004 if (
this == &a_other || a_other.
m_size == 0) {
1008 this->
swap(a_other);
1023 CH_assert(a_index <
m_size);
1025 return this->
gatherPayload(a_index, std::make_index_sequence<s_numPayloadColumns>{});
1035 CH_assert(a_index <
m_size);
1037 this->
removeImpl(a_index, std::make_index_sequence<s_numColumns>{});
1054 template <std::
size_t K>
1066 template <std::
size_t K>
1067 const ColumnType<K>*
1078 template <auto Member>
1082 return this->
template columnByIndex<columnIndex(Member)>();
1090 template <auto Member>
1094 return this->
template columnByIndex<columnIndex(Member)>();
1103 template <auto Member>
1105 get(
const std::size_t a_index)
noexcept
1107 CH_assert(a_index <
m_size);
1109 return this->
template columnByIndex<columnIndex(Member)>()[a_index];
1118 template <auto Member>
1120 get(
const std::size_t a_index)
const noexcept
1122 CH_assert(a_index <
m_size);
1124 return this->
template columnByIndex<columnIndex(Member)>()[a_index];
1141 return reinterpret_cast<double*
>(
m_colPtrs[a_dir]);
1152 return reinterpret_cast<const double*
>(
m_colPtrs[a_dir]);
1162 return this->
template columnByIndex<s_weightCol>();
1172 return this->
template columnByIndex<s_weightCol>();
1190 CH_assert(a_index <
m_size);
1193 for (
int dir = 0; dir < SpaceDim; dir++) {
1206 setPosition(
const std::size_t a_index,
const RealVect& a_position)
noexcept
1208 CH_assert(a_index <
m_size);
1211 for (
int dir = 0; dir < SpaceDim; dir++) {
1224 CH_assert(a_index <
m_size);
1226 return this->
template columnByIndex<s_weightCol>()[a_index];
1235 weight(
const std::size_t a_index)
const noexcept
1237 CH_assert(a_index <
m_size);
1239 return this->
template columnByIndex<s_weightCol>()[a_index];
1255 CH_assert(a_index <
m_size);
1257 return this->
template columnByIndex<s_idCol>()[a_index];
1268 CH_assert(a_index <
m_size);
1270 return this->
template columnByIndex<s_idCol>()[a_index];
1281 CH_assert(a_index <
m_size);
1283 return this->
template columnByIndex<s_rankCol>()[a_index];
1292 rankID(
const std::size_t a_index)
const noexcept
1294 CH_assert(a_index <
m_size);
1296 return this->
template columnByIndex<s_rankCol>()[a_index];
1305 ghost(
const std::size_t a_index)
noexcept
1307 CH_assert(a_index <
m_size);
1309 return this->
template columnByIndex<s_ghostCol>()[a_index];
1318 ghost(
const std::size_t a_index)
const noexcept
1320 CH_assert(a_index <
m_size);
1322 return this->
template columnByIndex<s_ghostCol>()[a_index];
1347 static constexpr std::size_t
1379 static constexpr std::size_t
1438 return this->
byteSpanImpl(std::make_index_sequence<s_numColumns>{});
1466 sortByCell(
const Box& a_box,
const RealVect& a_dx,
const RealVect& a_probLo);
1488 isSortedAgainst(
const Box& a_box,
const RealVect& a_dx,
const RealVect& a_probLo)
const noexcept
1512 CH_assert(a_cell <= this->
numCells());
1526 CH_assert(a_cell < this->
numCells());
1538 std::pair<std::size_t, std::size_t>
1542 CH_assert(a_cell < this->
numCells());
1565 const std::pair<std::size_t, std::size_t> range = this->
cellRange(a_cell);
1566 for (std::size_t i = range.first; i < range.second; i++) {
1640 cellKey(
const std::size_t a_index,
const Box& a_box,
const RealVect& a_dx,
const RealVect& a_probLo)
const noexcept
1642 const IntVect loEnd = a_box.smallEnd();
1643 const IntVect boxSize = a_box.size();
1644 const RealVect x = this->
position(a_index);
1646 std::size_t lin = 0;
1647 std::size_t stride = 1;
1648 for (
int d = 0; d < SpaceDim; d++) {
1649 int c =
static_cast<int>(std::floor((x[d] - a_probLo[d]) / a_dx[d])) - loEnd[d];
1653 if (c >= boxSize[d]) {
1656 lin +=
static_cast<std::size_t
>(c) * stride;
1657 stride *=
static_cast<std::size_t
>(boxSize[d]);
1675 checkCellSort(
const Box& a_box,
const RealVect& a_dx,
const RealVect& a_probLo)
const noexcept
1680 if (
m_cellStart.size() !=
static_cast<std::size_t
>(a_box.numPts()) + 1) {
1687 for (std::size_t c = 0; c < this->
numCells(); c++) {
1693 if (this->
cellKey(i, a_box, a_dx, a_probLo) != c) {
1730 a_o.m_buffer =
nullptr;
1734 a_o.m_sorted =
false;
1764 const std::size_t doubled = (
m_capacity == 0) ? 16
1765 : (m_capacity <= std::numeric_limits<std::size_t>::max() / 2
1767 : std::numeric_limits<std::size_t>::max());
1769 this->
reserve(std::max(a_needed, doubled));
1779 this->
growTo(m_size + 1);
1790 template <std::size_t... I>
1793 std::array<std::size_t, s_numColumns>& a_off,
1794 std::index_sequence<I...>)
const noexcept
1796 std::size_t running = 0;
1797 using expander =
int[];
1798 (void)expander{0, (a_off[I] = running, running +=
alignUp(a_capacity *
sizeof(
ColumnType<I>)), 0)...};
1807 template <std::size_t... I>
1809 setColPtrs(
const std::array<std::size_t, s_numColumns>& a_off, std::index_sequence<I...>)
noexcept
1811 using expander =
int[];
1812 (void)expander{0, (
m_colPtrs[I] =
static_cast<char*
>(
m_buffer) + a_off[I], 0)...};
1821 template <std::size_t... I>
1823 moveColumns(
void* a_newBuf,
const std::array<std::size_t, s_numColumns>& a_off, std::index_sequence<I...>)
noexcept
1825 using expander =
int[];
1838 template <std::size_t... I>
1842 using expander =
int[];
1855 template <std::size_t... I>
1859 using expander =
int[];
1862 a_other.m_colPtrs[I],
1876 template <std::size_t... I>
1879 const std::size_t a_srcIdx,
1880 const std::size_t a_dstIdx,
1881 std::index_sequence<I...>)
noexcept
1883 using expander =
int[];
1885 (this->
template columnByIndex<I>()[a_dstIdx] = a_src.template columnByIndex<I>()[a_srcIdx], 0)...};
1900 permute(
const std::vector<std::size_t>& a_dest);
1909 template <std::
size_t K>
1911 scatterColumn(
void* a_newBuf,
const std::size_t a_off,
const std::vector<std::size_t>& a_dest)
noexcept
1913 const ColumnType<K>* src = this->
template columnByIndex<K>();
1915 for (std::size_t i = 0; i <
m_size; i++) {
1916 dst[a_dest[i]] = src[i];
1927 template <std::size_t... I>
1930 const std::array<std::size_t, s_numColumns>& a_off,
1931 const std::vector<std::size_t>& a_dest,
1932 std::index_sequence<I...>)
noexcept
1934 using expander =
int[];
1935 (void)expander{0, ((void)this->
template scatterColumn<I>(a_newBuf, a_off[I], a_dest), 0)...};
1943 template <std::size_t... J>
1947 constexpr auto cols = Traits::columns;
1948 using expander =
int[];
1950 ((void)(this->
template columnByIndex<s_payloadBegin + J>()[
m_size] = a_p.*std::get<J>(cols)), 0)...};
1959 template <std::size_t... J>
1963 constexpr auto cols = Traits::columns;
1965 using expander =
int[];
1967 ((void)(p.*std::get<J>(cols) = this->
template columnByIndex<s_payloadBegin + J>()[a_index]), 0)...};
1976 template <std::size_t... I>
1978 removeImpl(
const std::size_t a_index, std::index_sequence<I...>)
noexcept
1980 using expander =
int[];
1983 ((void)(this->
template columnByIndex<I>()[a_index] = this->
template columnByIndex<I>()[
m_size - 1]), 0)...};
1992 template <std::size_t... I>
1994 linearizeImpl(
unsigned char* a_buf,
const std::size_t a_index, std::index_sequence<I...>)
const noexcept
1996 using expander =
int[];
1997 (void)expander{0, ((void)detail::pushBytes(a_buf, this->
template columnByIndex<I>()[a_index]), 0)...};
2005 template <std::size_t... I>
2009 using expander =
int[];
2010 (void)expander{0, ((void)this->
template pullColumn<I>(a_buf), 0)...};
2018 template <std::
size_t K>
2022 detail::pullBytes(a_buf, this->
template columnByIndex<K>()[
m_size]);
2030 template <std::size_t... J>
2031 static constexpr std::size_t
2043 template <std::size_t... J>
2045 h5LinearizePayload(
unsigned char*& a_buf,
const std::size_t a_index, std::index_sequence<J...>)
const noexcept
2047 using expander =
int[];
2049 ((void)detail::pushBytes(a_buf, this->
template columnByIndex<s_payloadBegin + J>()[a_index]), 0)...};
2057 template <std::size_t... J>
2061 using expander =
int[];
2063 ((void)detail::pullBytes(a_buf, this->
template columnByIndex<s_payloadBegin + J>()[
m_size]), 0)...};
2071 template <std::size_t... I>
2075 std::size_t span = 0;
2076 using expander =
int[];
2078 (span = (span > (
static_cast<std::size_t
>(
static_cast<const char*
>(
m_colPtrs[I]) -
2079 static_cast<const char*
>(
m_buffer)) +
2082 : (
static_cast<std::size_t
>(
static_cast<const char*
>(
m_colPtrs[I]) -
2083 static_cast<const char*
>(
m_buffer)) +
2090#include <CD_NamespaceFooter.H>
Process-wide accounting of the memory held by particle data.
Implementation of CD_ParticleSoA.H.
constexpr bool eqMember(A, B) noexcept
Type-mismatched overload of the pointer-to-member equality (always false).
Definition CD_ParticleSoA.H:339
#define CD_PARTICLE_REAL
Compile-time precision of particle PAYLOAD data. Defaults to double; define CD_PARTICLE_REAL (e....
Definition CD_ParticleSoA.H:150
void pushBytes(unsigned char *&a_buf, const T &a_value) noexcept
memcpy one trivially-copyable value onto a byte buffer and advance the buffer pointer.
Definition CD_ParticleSoA.H:590
constexpr std::size_t indexOf(const Tup &a_t, M a_target) noexcept
Compile-time index of a member pointer within a tuple (tuple size if absent).
Definition CD_ParticleSoA.H:398
constexpr std::size_t indexOfImpl(const Tup &, M, std::index_sequence<>) noexcept
Base case of the compile-time member-pointer index search (empty sequence).
Definition CD_ParticleSoA.H:366
typename MakeVoid< Ts... >::Type Void
Alias yielding void for any type pack (SFINAE helper, like std::void_t).
Definition CD_ParticleSoA.H:532
std::int32_t RankID
Owning-rank identifier type (container-owned metadata column; fixed-width for I/O).
Definition CD_ParticleSoA.H:166
GhostType
Ghost designation of a particle (container-owned metadata column).
Definition CD_ParticleSoA.H:177
@ SameLevel
Ghost from an adjacent patch on the same level.
@ Coarse
Ghost from the next-coarser level (level l-1).
@ Valid
Owned, valid particle of this patch (not a ghost).
@ Fine
Ghost from the next-finer level (level l+1).
constexpr std::index_sequence< indexOf(Traits::columns, std::get< I >(Traits::h5Columns))... > deriveH5Seq(std::index_sequence< I... > a_seq) noexcept
Turn a tuple of HDF5 payload member pointers into a std::index_sequence of DERIVED payload-column ind...
Definition CD_ParticleSoA.H:544
void pullBytes(const unsigned char *&a_buf, T &a_value) noexcept
memcpy one trivially-copyable value off a byte buffer and advance the buffer pointer.
Definition CD_ParticleSoA.H:605
CD_PARTICLE_REAL ParticleReal
Floating-point type a user may use for payload columns.
Definition CD_ParticleSoA.H:156
constexpr std::size_t sumSizes() noexcept
Base case of the variadic constexpr size sum (no arguments).
Definition CD_ParticleSoA.H:456
std::int64_t ParticleID
Global particle identifier type (container-owned metadata column; fixed-width for I/O).
Definition CD_ParticleSoA.H:161
Arena-backed Struct-of-Arrays particle container for a single grid patch.
Definition CD_ParticleSoA.H:655
void h5DelinearizePayload(const unsigned char *&a_buf, std::index_sequence< J... >) noexcept
Pull the HDF5 payload subset off a byte buffer into slot m_size.
Definition CD_ParticleSoA.H:2059
static constexpr std::size_t s_weightCol
Column index of the weight (immediately after the SpaceDim position columns).
Definition CD_ParticleSoA.H:675
void permute(const std::vector< std::size_t > &a_dest)
Reorder every column in place by a_dest (a_dest[i] = new slot of old particle i).
Definition CD_ParticleSoAImplem.H:60
void h5LinearizePayload(unsigned char *&a_buf, const std::size_t a_index, std::index_sequence< J... >) const noexcept
Push the HDF5 payload subset of particle a_index onto a byte buffer.
Definition CD_ParticleSoA.H:2045
void sortByCell(const Box &a_box, const RealVect &a_dx, const RealVect &a_probLo)
Counting-sort the columns into Fortran cell order and build CSR cell offsets.
Definition CD_ParticleSoAImplem.H:303
RankID & rankID(const std::size_t a_index) noexcept
Owning rank of particle i (container-owned metadata).
Definition CD_ParticleSoA.H:1279
void append(const RealVect &a_position, const double a_weight)
Append one particle with a default-constructed payload.
Definition CD_ParticleSoA.H:955
const ParticleID & particleID(const std::size_t a_index) const noexcept
Const global id of particle i.
Definition CD_ParticleSoA.H:1266
ColumnType< K > * columnByIndex() noexcept
Typed base pointer of column K (low-level).
Definition CD_ParticleSoA.H:1056
void shrinkToFit()
Reclaim unused capacity by reallocating the arena down to the current size.
Definition CD_ParticleSoAImplem.H:187
double * weightColumn() noexcept
Raw weight column (double*).
Definition CD_ParticleSoA.H:1160
bool m_sorted
Whether m_cellStart is valid.
Definition CD_ParticleSoA.H:1602
bool isGhost(const std::size_t a_index) const noexcept
Whether particle i is a ghost particle (any non-Valid designation).
Definition CD_ParticleSoA.H:1331
void delinearizeAndAppend(const void *a_buffer)
Append a particle delinearized from a byte buffer (all columns, for MPI receive).
Definition CD_ParticleSoAImplem.H:243
void removeImpl(const std::size_t a_index, std::index_sequence< I... >) noexcept
Swap-and-pop slot a_index in every column.
Definition CD_ParticleSoA.H:1978
void linearizeParticle(void *a_buffer, const std::size_t a_index) const noexcept
Linearize particle i into a byte buffer (all columns, for MPI send).
Definition CD_ParticleSoAImplem.H:232
const double & weight(const std::size_t a_index) const noexcept
Const weight of particle i.
Definition CD_ParticleSoA.H:1235
const auto * column() const noexcept
Const whole payload column selected by member pointer.
Definition CD_ParticleSoA.H:1092
decltype(std::tuple_cat(std::declval< MandatoryValues >(), std::declval< PayloadValues >())) ColumnValueTuple
The value types of every column, in storage order.
Definition CD_ParticleSoA.H:735
std::size_t particlesInCell(const std::size_t a_cell) const noexcept
Number of particles in cell c (valid after sortByCell).
Definition CD_ParticleSoA.H:1523
auto & get(const std::size_t a_index) noexcept
One particle's payload field selected by member pointer.
Definition CD_ParticleSoA.H:1105
void steal(ParticleSoA &a_o) noexcept
Steal another container's arena (move helper).
Definition CD_ParticleSoA.H:1718
std::size_t m_capacity
Capacity in particles.
Definition CD_ParticleSoA.H:1582
RealVect position(const std::size_t a_index) const noexcept
Position of particle i as a RealVect (by value, assembled from the scalar columns).
Definition CD_ParticleSoA.H:1188
GhostType & ghost(const std::size_t a_index) noexcept
Ghost designation of particle i (container-owned metadata).
Definition CD_ParticleSoA.H:1305
double & weight(const std::size_t a_index) noexcept
Weight of particle i.
Definition CD_ParticleSoA.H:1222
std::size_t numCells() const noexcept
Number of cells in the CSR sort (0 if not sorted).
Definition CD_ParticleSoA.H:1498
static constexpr std::size_t bytesPerParticle() noexcept
Byte count of one fully-linearized particle (all columns, for MPI).
Definition CD_ParticleSoA.H:1348
void deepCopyTo(ParticleSoA &a_dst) const
Deep copy into an existing destination, reusing its arena when possible.
Definition CD_ParticleSoAImplem.H:130
static constexpr std::size_t s_align
Cache-line alignment for each column (also enables aligned SIMD).
Definition CD_ParticleSoA.H:705
void setColPtrs(const std::array< std::size_t, s_numColumns > &a_off, std::index_sequence< I... >) noexcept
Cache the column base pointers from a fresh buffer + offsets.
Definition CD_ParticleSoA.H:1809
const void * data() const noexcept
Raw arena pointer (column-major); a compact container's whole data span.
Definition CD_ParticleSoA.H:1413
static constexpr std::size_t h5PayloadSize(std::index_sequence< J... >) noexcept
Compile-time byte size of the HDF5 payload subset.
Definition CD_ParticleSoA.H:2032
std::size_t size() const noexcept
Number of particles currently stored.
Definition CD_ParticleSoA.H:882
void setPosition(const std::size_t a_index, const RealVect &a_position) noexcept
Set the position of particle i.
Definition CD_ParticleSoA.H:1206
static constexpr std::size_t s_numColumns
Total number of columns (SpaceDim position + weight + id + rank + ghost + payload).
Definition CD_ParticleSoA.H:700
static constexpr std::size_t s_numPayloadColumns
Number of user-declared payload columns.
Definition CD_ParticleSoA.H:670
std::size_t m_size
Live particle count.
Definition CD_ParticleSoA.H:1597
typename detail::H5ColumnSubset< Traits, std::make_index_sequence< s_numPayloadColumns > >::Type H5PayloadColumns
The HDF5 payload column subset (indices into the payload columns).
Definition CD_ParticleSoA.H:759
std::size_t byteSpanImpl(std::index_sequence< I... >) const noexcept
Byte span of the live data: max over columns of (offset + used bytes).
Definition CD_ParticleSoA.H:2073
std::size_t computeOffsets(const std::size_t a_capacity, std::array< std::size_t, s_numColumns > &a_off, std::index_sequence< I... >) const noexcept
Compute per-column byte offsets for a given capacity; returns the total bytes.
Definition CD_ParticleSoA.H:1792
double * positionColumn(const int a_dir) noexcept
Raw position component column dir (double*, for SIMD kernels).
Definition CD_ParticleSoA.H:1137
void copyLiveColumnsTo(ParticleSoA &a_dst, std::index_sequence< I... >) const noexcept
Copy this container's m_size live elements of every column into another container.
Definition CD_ParticleSoA.H:1840
void appendColumnsFrom(const ParticleSoA &a_other, const std::size_t a_at, std::index_sequence< I... >) noexcept
Bulk-append another container's live columns at slot a_at of this container's columns.
Definition CD_ParticleSoA.H:1857
~ParticleSoA()
Destructor (frees the arena).
Definition CD_ParticleSoA.H:781
ParticleSoA deepCopy() const
Explicit deep copy: a new container with a private arena duplicating every particle.
Definition CD_ParticleSoAImplem.H:109
void h5DelinearizeAndAppend(const void *a_buffer)
Append a particle whose HDF5-checkpointed columns come from a buffer.
Definition CD_ParticleSoAImplem.H:275
void extractCell(const std::size_t a_cell, ParticleSoA &a_out) const
Extract cell c's particles (the CSR range [cellStart(c), cellStart(c+1))) into a_out.
Definition CD_ParticleSoA.H:1559
void h5LinearizeParticle(void *a_buffer, const std::size_t a_index) const noexcept
Linearize the HDF5-checkpointed columns of particle i (no id/rank).
Definition CD_ParticleSoAImplem.H:258
void linearizeImpl(unsigned char *a_buf, const std::size_t a_index, std::index_sequence< I... >) const noexcept
Push every column of particle a_index onto a byte buffer (MPI).
Definition CD_ParticleSoA.H:1994
void pullColumn(const unsigned char *&a_buf) noexcept
Pull one column's value off a byte buffer into slot m_size and advance the pointer.
Definition CD_ParticleSoA.H:2020
void scatterColumn(void *a_newBuf, const std::size_t a_off, const std::vector< std::size_t > &a_dest) noexcept
Per-column scatter for permute(): newcol[dest[i]] = oldcol[i].
Definition CD_ParticleSoA.H:1911
static constexpr std::size_t h5BytesPerParticle() noexcept
Bytes for one HDF5-linearized particle (position + weight + h5 payload subset).
Definition CD_ParticleSoA.H:1380
std::array< void *, s_numColumns > m_colPtrs
Cached column base pointers into m_buffer.
Definition CD_ParticleSoA.H:1607
P gather(const std::size_t a_index) const
Gather particle i's payload back into the AoS payload view.
Definition CD_ParticleSoA.H:1021
void * m_buffer
The single arena allocation.
Definition CD_ParticleSoA.H:1577
void delinearizeImpl(const unsigned char *a_buf, std::index_sequence< I... >) noexcept
Pull every column of one particle off a byte buffer into slot m_size (MPI).
Definition CD_ParticleSoA.H:2007
void resize(const std::size_t a_count)
Set the particle count (grows capacity if needed; new slots are uninitialized).
Definition CD_ParticleSoAImplem.H:99
void writePayload(const P &a_p, std::index_sequence< J... >) noexcept
Write the payload columns of slot m_size from a payload struct.
Definition CD_ParticleSoA.H:1945
std::size_t m_bytes
Byte size of the arena at m_buffer (zero when m_buffer is null).
Definition CD_ParticleSoA.H:1592
std::size_t capacity() const noexcept
Allocated capacity in particles.
Definition CD_ParticleSoA.H:892
static std::size_t alignUp(const std::size_t a_x) noexcept
Round a_x up to the next multiple of s_align.
Definition CD_ParticleSoA.H:1708
void scatterColumns(void *a_newBuf, const std::array< std::size_t, s_numColumns > &a_off, const std::vector< std::size_t > &a_dest, std::index_sequence< I... >) noexcept
Scatter every column for permute() into a freshly-allocated buffer.
Definition CD_ParticleSoA.H:1929
const GhostType & ghost(const std::size_t a_index) const noexcept
Const ghost designation of particle i.
Definition CD_ParticleSoA.H:1318
ParticleID & particleID(const std::size_t a_index) noexcept
Global id of particle i (container-owned metadata).
Definition CD_ParticleSoA.H:1253
const ColumnType< K > * columnByIndex() const noexcept
Const typed base pointer of column K (low-level).
Definition CD_ParticleSoA.H:1068
ParticleSoA & operator=(const ParticleSoA &)=delete
Copy assignment is deleted (move-only).
std::pair< std::size_t, std::size_t > cellRange(const std::size_t a_cell) const noexcept
Half-open particle index range [begin, end) owned by cell c (valid after sortByCell).
Definition CD_ParticleSoA.H:1539
static constexpr std::size_t s_rankCol
Column index of the container-owned rankID.
Definition CD_ParticleSoA.H:685
std::vector< std::size_t > m_cellStart
CSR cell offsets (size numCells+1 when sorted).
Definition CD_ParticleSoA.H:1612
void catenate(ParticleSoA &a_other)
Move every particle of another container into this one, leaving a_other empty (catenate).
Definition CD_ParticleSoA.H:1002
std::remove_cv_t< std::remove_reference_t< decltype(Traits::columns)> > PayloadColumns
The payload columns descriptor tuple type (tuple of pointer-to-member).
Definition CD_ParticleSoA.H:665
std::size_t cellKey(const std::size_t a_index, const Box &a_box, const RealVect &a_dx, const RealVect &a_probLo) const noexcept
Compute the Fortran (x-fastest) cell index of particle i within the sort domain.
Definition CD_ParticleSoA.H:1640
RealVect m_sortDx
Grid spacing the CSR mapping was built against (meaningful only when m_sorted).
Definition CD_ParticleSoA.H:1622
void remove(const std::size_t a_index) noexcept
Remove particle i using swap-and-pop (O(1), does NOT preserve order).
Definition CD_ParticleSoA.H:1033
static constexpr ParticleID s_invalidID
Sentinel for an unassigned/invalid global particle id.
Definition CD_ParticleSoA.H:1245
void swap(ParticleSoA &a_other) noexcept
Swap the entire state (arena, size, capacity, sort) with another container in O(1).
Definition CD_ParticleSoA.H:856
bool empty() const noexcept
Whether the container holds no particles.
Definition CD_ParticleSoA.H:902
static constexpr std::size_t s_payloadBegin
Index of the first payload column.
Definition CD_ParticleSoA.H:695
void * data() noexcept
Mutable raw arena pointer (e.g. zero-copy MPI receive into the arena).
Definition CD_ParticleSoA.H:1423
void growTo(const std::size_t a_needed)
Grow the arena to hold at least a_needed particles, geometrically.
Definition CD_ParticleSoA.H:1756
ParticleSoA & operator=(ParticleSoA &&a_other) noexcept
Move assignment (steals the arena).
Definition CD_ParticleSoA.H:815
void growIfFull()
Grow geometrically if the container is full (called before writing slot m_size).
Definition CD_ParticleSoA.H:1776
RealVect m_sortProbLo
Lower domain corner the CSR mapping was built against (meaningful only when m_sorted).
Definition CD_ParticleSoA.H:1627
P gatherPayload(const std::size_t a_index, std::index_sequence< J... >) const
Read the payload columns of slot a_index into a payload struct.
Definition CD_ParticleSoA.H:1961
void copyParticleColumns(const ParticleSoA &a_src, const std::size_t a_srcIdx, const std::size_t a_dstIdx, std::index_sequence< I... >) noexcept
Copy one particle's every column from a_src[a_srcIdx] into this[a_dstIdx].
Definition CD_ParticleSoA.H:1878
auto * column() noexcept
Whole payload column selected by member pointer (raw pointer, vectorizable).
Definition CD_ParticleSoA.H:1080
const auto & get(const std::size_t a_index) const noexcept
Const overload of get<&P::field>(i).
Definition CD_ParticleSoA.H:1120
Box m_sortBox
Patch box the CSR mapping in m_cellStart was built against (meaningful only when m_sorted).
Definition CD_ParticleSoA.H:1617
bool isSortedAgainst(const Box &a_box, const RealVect &a_dx, const RealVect &a_probLo) const noexcept
Whether the container is cell-sorted against exactly this cell domain.
Definition CD_ParticleSoA.H:1488
ParticleSoA(const ParticleSoA &)=delete
Copy construction is deleted (move-only).
const double * positionColumn(const int a_dir) const noexcept
Const raw position component column dir.
Definition CD_ParticleSoA.H:1150
void moveColumns(void *a_newBuf, const std::array< std::size_t, s_numColumns > &a_off, std::index_sequence< I... >) noexcept
Contiguously memcpy every column's live region into a freshly-allocated buffer.
Definition CD_ParticleSoA.H:1823
static constexpr std::size_t columnIndex(const M a_member) noexcept
Derive the column index of a PAYLOAD member pointer (reorder-safe selector).
Definition CD_ParticleSoA.H:751
std::size_t byteSpan() const noexcept
Byte span of the live data (for a compact container, one contiguous memcpy/MPI_Send).
Definition CD_ParticleSoA.H:1433
ParticleSoA(ParticleSoA &&a_other) noexcept
Move constructor (steals the arena).
Definition CD_ParticleSoA.H:804
static constexpr std::size_t s_idCol
Column index of the container-owned particleID.
Definition CD_ParticleSoA.H:680
void clear() noexcept
Drop all particles (keeps the arena; invalidates the cell sort).
Definition CD_ParticleSoA.H:911
void appendParticle(const ParticleSoA &a_src, const std::size_t a_index)
Append a single particle (all columns, incl. id/rank) copied from another container.
Definition CD_ParticleSoAImplem.H:172
bool checkCellSort(const Box &a_box, const RealVect &a_dx, const RealVect &a_probLo) const noexcept
Verify that the CSR mapping really does describe the current particle positions.
Definition CD_ParticleSoA.H:1675
bool isSorted() const noexcept
Whether the container is currently cell-sorted (false after append/remove).
Definition CD_ParticleSoA.H:1473
void reallocate(const std::size_t a_capacity)
Allocate a new arena and reallocate/move the columns into it (growth path).
Definition CD_ParticleSoAImplem.H:29
ParticleSoA()=default
Construct an empty container.
const double * weightColumn() const noexcept
Const raw weight column.
Definition CD_ParticleSoA.H:1170
static constexpr std::size_t s_ghostCol
Column index of the container-owned ghost designation.
Definition CD_ParticleSoA.H:690
std::size_t cellStart(const std::size_t a_cell) const noexcept
CSR start offset of cell c (valid after sortByCell; requires c <= numCells()).
Definition CD_ParticleSoA.H:1509
const RankID & rankID(const std::size_t a_index) const noexcept
Const owning rank of particle i.
Definition CD_ParticleSoA.H:1292
void reserve(const std::size_t a_capacity)
Ensure capacity for at least a_capacity particles (reallocates + moves on growth).
Definition CD_ParticleSoAImplem.H:88
std::tuple_element_t< K, ColumnValueTuple > ColumnType
Value type of column K.
Definition CD_ParticleSoA.H:741
Declarative descriptors for selecting which particle PAYLOAD columns are written to H5Part (visualiza...
Definition CD_ParticleSoA.H:212
void removeBytes(const Kind a_kind, const std::size_t a_bytes) noexcept
Record a release.
Definition CD_ParticleMemory.H:140
@ Container
ParticleSoA arenas: capacity a rank is holding.
Descriptor of a single scalar payload column written to one H5Part dataset.
Definition CD_ParticleSoA.H:220
const char * name
H5Part dataset name.
Definition CD_ParticleSoA.H:229
M member
Pointer-to-member selecting the payload column.
Definition CD_ParticleSoA.H:234
static constexpr bool s_isVector
Tag identifying this descriptor as a scalar (single-component) column.
Definition CD_ParticleSoA.H:224
Descriptor of a SpaceDim-component vector payload column, written as name-x/name-y/name-z.
Definition CD_ParticleSoA.H:250
const char * name
H5Part dataset base name (datasets are name-x/name-y/name-z).
Definition CD_ParticleSoA.H:259
static constexpr bool s_isVector
Tag identifying this descriptor as a vector (multi-component) column.
Definition CD_ParticleSoA.H:254
std::tuple< Ms... > members
Pointers-to-member selecting the per-component payload columns.
Definition CD_ParticleSoA.H:264
constexpr Vector(const char *a_name, Ms... a_members) noexcept
Constructor.
Definition CD_ParticleSoA.H:271
Empty payload: ParticleSoA<> is a position+weight+metadata point particle.
Definition CD_ParticleSoA.H:289
Traits class that a user specializes to describe the PAYLOAD columns of a particle type....
Definition CD_ParticleSoA.H:192
Primary template for "every type in a value tuple is trivially copyable".
Definition CD_ParticleSoA.H:500
decltype(deriveH5Seq< Traits >(std::make_index_sequence< std::tuple_size< H5Tuple >::value >{})) Type
Derived payload-column index subset.
Definition CD_ParticleSoA.H:579
std::remove_cv_t< std::remove_reference_t< decltype(Traits::h5Columns)> > H5Tuple
The declared h5Columns tuple type.
Definition CD_ParticleSoA.H:575
Primary template resolving the HDF5 payload column subset; defaults to all columns.
Definition CD_ParticleSoA.H:557
Fallback Type
The resolved subset (all payload columns).
Definition CD_ParticleSoA.H:561
Stand-in for std::void_t (maps any type pack to void).
Definition CD_ParticleSoA.H:521
void Type
Always void.
Definition CD_ParticleSoA.H:525
T ValueType
Value type of the member.
Definition CD_ParticleSoA.H:328
C ClassType
Class that owns the member.
Definition CD_ParticleSoA.H:324
Primary template that extracts the class and value type from a pointer-to-member type.
Definition CD_ParticleSoA.H:311
std::tuple of N copies of T (used to build the SpaceDim position columns).
Definition CD_ParticleSoA.H:410
static std::tuple< Always< I >... > make(std::index_sequence< I... >)
Deduce the repeated-tuple type from an index sequence (declaration only).
decltype(make(std::make_index_sequence< N >{})) Type
The resulting std::tuple type.
Definition CD_ParticleSoA.H:428
T Always
Helper alias that maps any index to T.
Definition CD_ParticleSoA.H:415
Primary template for the compile-time sum of sizeof() over a value tuple.
Definition CD_ParticleSoA.H:480
std::tuple< typename MemberPointerTraits< Ms >::ValueType... > Type
Tuple of member value types.
Definition CD_ParticleSoA.H:448
Primary template mapping a tuple of pointer-to-member to the tuple of value types.
Definition CD_ParticleSoA.H:436