13#ifndef CD_PARTICLEOPSIMPLEM_H
14#define CD_PARTICLEOPSIMPLEM_H
29#include <CD_NamespaceHeader.H>
33 const RealVect& a_probLo,
34 const Real& a_dx)
noexcept
36 return IntVect(D_DECL(std::floor((a_particlePosition[0] - a_probLo[0]) / a_dx),
37 std::floor((a_particlePosition[1] - a_probLo[1]) / a_dx),
38 std::floor((a_particlePosition[2] - a_probLo[2]) / a_dx)));
43 const RealVect& a_probLo,
44 const RealVect& a_dx)
noexcept
46 return IntVect(D_DECL(std::floor((a_particlePosition[0] - a_probLo[0]) / a_dx[0]),
47 std::floor((a_particlePosition[1] - a_probLo[1]) / a_dx[1]),
48 std::floor((a_particlePosition[2] - a_probLo[2]) / a_dx[2])));
51template <
typename P,
typename Traits>
55 CH_TIME(
"ParticleOps::getPhysicalParticlesPerCell(SoA)");
57 const RealVect probLo = a_src.getProbLo();
59 for (
int lvl = 0; lvl <= a_src.getFinestLevel(); lvl++) {
60 const DisjointBoxLayout& dbl = a_src.getGrids()[lvl];
61 const DataIterator& dit = dbl.dataIterator();
62 const RealVect dx = a_src.getDx()[lvl];
64 const int nbox = dit.size();
66#pragma omp parallel for schedule(runtime)
67 for (
int mybox = 0; mybox < nbox; mybox++) {
68 const DataIndex& din = dit[mybox];
71 FArrayBox& ppc = (*a_ppc[lvl])[din].getFArrayBox();
74 for (std::size_t i = 0; i < leaf.
size(); i++) {
77 ppc(iv, 0) += leaf.
weight(i);
83template <
typename P,
typename Traits>
87 CH_TIME(
"ParticleOps::getComputationalParticlesPerCell(SoA)");
89 const RealVect probLo = a_src.getProbLo();
91 for (
int lvl = 0; lvl <= a_src.getFinestLevel(); lvl++) {
92 const DisjointBoxLayout& dbl = a_src.getGrids()[lvl];
93 const DataIterator& dit = dbl.dataIterator();
94 const RealVect dx = a_src.getDx()[lvl];
96 const int nbox = dit.size();
98#pragma omp parallel for schedule(runtime)
99 for (
int mybox = 0; mybox < nbox; mybox++) {
100 const DataIndex& din = dit[mybox];
103 FArrayBox& ppc = (*a_ppc[lvl])[din].getFArrayBox();
106 for (std::size_t i = 0; i < leaf.
size(); i++) {
117 const RealVect& a_probLo,
118 const RealVect& a_dx)
noexcept
120 return IntVect(D_DECL(std::floor((a_particlePosition[0] - a_probLo[0]) / a_dx[0]),
121 std::floor((a_particlePosition[1] - a_probLo[1]) / a_dx[1]),
122 std::floor((a_particlePosition[2] - a_probLo[2]) / a_dx[2])));
127 const RealVect& a_newPos,
128 const RealVect& a_probLo,
129 const RealVect& a_probHi,
138 a_s = std::numeric_limits<Real>::max();
140 bool crossedDomainBoundary =
false;
142 const RealVect path = a_newPos - a_oldPos;
144 for (
int dir = 0; dir < SpaceDim; dir++) {
145 for (SideIterator sit; sit.ok(); ++sit) {
147 const Side::LoHiSide side = sit();
148 const RealVect wallPoint = (side == Side::Lo) ? a_probLo : a_probHi;
149 const RealVect n0 = sign(side) * RealVect(BASISV(dir));
150 const Real normPath = PolyGeom::dot(n0, path);
154 if (normPath > 0.0) {
159 const Real s = PolyGeom::dot(wallPoint - a_oldPos, n0) / normPath;
160 if (s >= 0.0 && s <= 1.0) {
161 crossedDomainBoundary =
true;
171 return crossedDomainBoundary;
176 const RealVect& a_oldPos,
177 const RealVect& a_newPos,
178 const Real& a_bisectStep,
187 a_s = std::numeric_limits<Real>::max();
189 bool crossedEB =
false;
191 const Real pathLen = (a_newPos - a_oldPos).vectorLength();
192 const int nsteps = ceil(pathLen / a_bisectStep);
193 const RealVect dxStep = (a_newPos - a_oldPos) / nsteps;
196 RealVect curPos = a_oldPos;
197 for (
int istep = 0; istep < nsteps; istep++) {
200 const Real fa = a_impFunc->value(curPos);
201 const Real fb = a_impFunc->value(curPos + dxStep);
203 if (fa * fb <= 0.0) {
210 a_s = (intersectionPos - a_oldPos).vectorLength() / pathLen;
225 const RealVect& a_oldPos,
226 const RealVect& a_newPos,
227 const Real& a_tolerance,
231 a_s = std::numeric_limits<Real>::max();
236 auto dist = [&](
const RealVect& x) -> Real {
237 return std::abs(a_impFunc->value(x));
240 const Real D = (a_newPos - a_oldPos).vectorLength();
241 const Real D0 = dist(a_oldPos);
247 const RealVect t = (a_newPos - a_oldPos) / D;
253 RealVect xa = a_oldPos;
259 if (d < a_tolerance) {
260 a_s = (xa - a_oldPos).vectorLength() / D;
276template <
typename P,
typename Traits>
280 CH_TIME(
"ParticleOps::copyDestructive(ParticleContainer<P, Traits> x2)");
282 CH_assert(a_dst.getRealm() == a_src.getRealm());
284 for (
int lvl = 0; lvl <= a_dst.getFinestLevel(); lvl++) {
285 const DisjointBoxLayout& dbl = a_dst.getGrids()[lvl];
286 const DataIterator& dit = dbl.dataIterator();
288 const int nbox = dit.size();
290#pragma omp parallel for schedule(runtime)
291 for (
int mybox = 0; mybox < nbox; mybox++) {
292 const DataIndex& din = dit[mybox];
294 a_dst[lvl][din].clear();
295 a_dst[lvl][din].catenate(a_src[lvl][din]);
300template <
typename P,
typename Traits>
304 CH_TIME(
"ParticleOps::sum(ParticleContainer<P>)");
306 Real particleSum = 0.0;
308 for (
int lvl = 0; lvl <= a_particles.getFinestLevel(); lvl++) {
309 const DisjointBoxLayout& dbl = a_particles.getGrids()[lvl];
310 const DataIterator& dit = dbl.dataIterator();
312 const int nbox = dit.size();
314#pragma omp parallel for schedule(runtime) reduction(+ : particleSum)
315 for (
int mybox = 0; mybox < nbox; mybox++) {
316 const DataIndex& din = dit[mybox];
332template <
typename P,
typename Traits>
337 CH_TIME(
"ParticleOps::setData(ParticleContainer<P>, std::function<void(ParticleSoA<P>&, std::size_t)>)");
340 const DisjointBoxLayout& dbl = a_particles.
getGrids()[lvl];
341 const DataIterator& dit = dbl.dataIterator();
343 const int nbox = dit.size();
345#pragma omp parallel for schedule(runtime)
346 for (
int mybox = 0; mybox < nbox; mybox++) {
347 const DataIndex& din = dit[mybox];
351 for (std::size_t i = 0; i < leaf.
size(); i++) {
358#include <CD_NamespaceFooter.H>
Agglomeration of basic MPI reductions.
Declaration of a namespace for SIMD-decorated loops over SoA particles.
Declaration of a static class containing some common useful particle routines that would otherwise be...
Agglomeration of some useful algebraic/polynomial routines.
File containing some useful static methods related to random number generation.
AMR-hierarchy container of computational particles, stored per patch in Struct-of-Arrays form.
Definition CD_ParticleContainer.H:123
int getFinestLevel() const
Finest AMR level index.
Definition CD_ParticleContainer.H:290
const Vector< DisjointBoxLayout > & getGrids() const
Per-level AMR grids.
Definition CD_ParticleContainer.H:260
static Real sum(const ParticleContainer< P, Traits > &a_particles) noexcept
Global sum of the container-owned weight column (SoA overload).
Definition CD_ParticleOpsImplem.H:302
static bool ebIntersectionRaycast(const RefCountedPtr< BaseIF > &a_impFunc, const RealVect &a_oldPos, const RealVect &a_newPos, const Real &a_tolerance, Real &a_s)
Compute the intersection point between a particle path and an implicit function using a ray-casting a...
Definition CD_ParticleOpsImplem.H:224
static bool ebIntersectionBisect(const RefCountedPtr< BaseIF > &a_impFunc, const RealVect &a_oldPos, const RealVect &a_newPos, const Real &a_bisectStep, Real &a_s)
Compute the intersection point between a particle path and an implicit function using a bisection alg...
Definition CD_ParticleOpsImplem.H:175
static void copyDestructive(ParticleContainer< P, Traits > &a_dst, ParticleContainer< P, Traits > &a_src) noexcept
Move all particles from a_src into a_dst (per leaf), emptying a_src. SoA overload.
Definition CD_ParticleOpsImplem.H:278
static void getComputationalParticlesPerCell(EBAMRCellData &a_ppc, const ParticleContainer< P, Traits > &a_src) noexcept
Get the number of computational particles per cell (SoA overload).
Definition CD_ParticleOpsImplem.H:85
static IntVect getParticleGridCell(const RealVect &a_particlePosition, const RealVect &a_probLo, const RealVect &a_dx) noexcept
Get the grid cell where the particle lives.
Definition CD_ParticleOpsImplem.H:116
static void setData(ParticleContainer< P, Traits > &a_particles, const std::function< void(ParticleSoA< P, Traits > &, std::size_t)> &a_functor) noexcept
Set value function for SoA containers. Lets the user set particle parameters via a (leaf,...
Definition CD_ParticleOpsImplem.H:334
static IntVect getParticleCellIndex(const RealVect &a_particlePosition, const RealVect &a_probLo, const Real &a_dx) noexcept
Get the cell index corresponding to the particle position.
Definition CD_ParticleOpsImplem.H:32
static void getPhysicalParticlesPerCell(EBAMRCellData &a_ppc, const ParticleContainer< P, Traits > &a_src) noexcept
Get the number of physical particles per cell (SoA overload).
Definition CD_ParticleOpsImplem.H:53
static bool domainIntersection(const RealVect &a_oldPos, const RealVect &a_newPos, const RealVect &a_probLo, const RealVect &a_probHi, Real &a_s)
Compute the intersection point between a particle path and a domain side.
Definition CD_ParticleOpsImplem.H:126
Arena-backed Struct-of-Arrays particle container for a single grid patch.
Definition CD_ParticleSoA.H:655
double * weightColumn() noexcept
Raw weight column (double*).
Definition CD_ParticleSoA.H:1160
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
double & weight(const std::size_t a_index) noexcept
Weight of particle i.
Definition CD_ParticleSoA.H:1222
std::size_t size() const noexcept
Number of particles currently stored.
Definition CD_ParticleSoA.H:882
Real sum(const Real &a_value) noexcept
Compute the sum across all MPI ranks.
Definition CD_ParallelOpsImplem.H:354
ALWAYS_INLINE T reduce(const ParticleSoA< P, Traits > &a_soa, T a_initial, Functor &&a_kernel)
Fold a kernel over every particle in a ParticleSoA, accumulating a reduction value.
Definition CD_ParticleLoops.H:122
RealVect brentRootFinder(const RefCountedPtr< BaseIF > &a_impFunc, const RealVect &a_point1, const RealVect &a_point2)
Compute the root of a function between two points. This is a 1D problem along the line.
Definition CD_PolyUtils.cpp:25