Skip to content

Commit 7ccf3c6

Browse files
RemiLeheclaude
andcommitted
Fix position-swap loop for charge exchange across all geometries
The previous `for (int idim = 0; idim < PIdx::w; ++idim)` loop assumed position attributes were stored at indices 0..PIdx::w-1, which is true for 1D_Z, XZ, and 3D, but NOT for RZ, RCYLINDER, and RSPHERE — there theta and phi come after `w` in PIdx. Replace with a range-based for over a `static constexpr std::array<int, N>` whose contents are selected per-dimension via `#if defined(WARPX_DIM_*)`. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 39fcf1d commit 7ccf3c6

1 file changed

Lines changed: 21 additions & 2 deletions

File tree

Source/Particles/Collision/BinaryCollision/DSMC/SplitAndScatterFunc.H

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,26 @@
1717
#include "Utils/ParticleUtils.H"
1818
#include "Utils/WarpXAlgorithmSelection.H"
1919

20+
#include <array>
21+
22+
// Indices in PIdx of the spatial-position attributes, for the current
23+
// dimensionality. Note that they are not contiguous in PIdx for RZ-family
24+
// geometries (theta/phi come after `w`), so a simple 0..PIdx::w-1 loop would
25+
// miss them.
26+
#if defined(WARPX_DIM_1D_Z)
27+
static constexpr std::array<int, 1> position_indices = {PIdx::z};
28+
#elif defined(WARPX_DIM_XZ)
29+
static constexpr std::array<int, 2> position_indices = {PIdx::x, PIdx::z};
30+
#elif defined(WARPX_DIM_RZ)
31+
static constexpr std::array<int, 3> position_indices = {PIdx::x, PIdx::z, PIdx::theta};
32+
#elif defined(WARPX_DIM_RCYLINDER)
33+
static constexpr std::array<int, 2> position_indices = {PIdx::x, PIdx::theta};
34+
#elif defined(WARPX_DIM_RSPHERE)
35+
static constexpr std::array<int, 3> position_indices = {PIdx::x, PIdx::theta, PIdx::phi};
36+
#elif defined(WARPX_DIM_3D)
37+
static constexpr std::array<int, 3> position_indices = {PIdx::x, PIdx::y, PIdx::z};
38+
#endif
39+
2040
/**
2141
* \brief This class defines an operator to create product particles from DSMC
2242
* collisions and sets the particle properties (position, momentum, weight).
@@ -360,9 +380,8 @@ public:
360380
// For charge exchange, swap positions at which the products are created
361381
// to ensure local charge conservation. For instance in the reaction
362382
// `A+ + B -> A + B+`, B+ will be created at the position of A+, instead of that of B.
363-
// Position components occupy indices 0 through PIdx::w-1 in m_rdata.
364383
if (mask[i] == int(ScatteringProcessType::CHARGE_EXCHANGE)) {
365-
for (int idim = 0; idim < PIdx::w; ++idim) {
384+
for (int idim : position_indices) {
366385
soa_products_data[2].m_rdata[idim][slot2_idx] = soa_1.m_rdata[idim][src1_idx];
367386
soa_products_data[3].m_rdata[idim][slot3_idx] = soa_0.m_rdata[idim][src0_idx];
368387
}

0 commit comments

Comments
 (0)