1#include <gtest/gtest.h>
10#include "Utility/IpplTimings.h"
16 char** argv =
nullptr;
18 ippl::initialize(argc, argv);
26 ippl::Vector<double, 3> rmin = -4.0;
27 ippl::Vector<double, 3> rmax = 4.0;
28 ippl::Vector<double, 3> origin = rmin;
29 ippl::Vector<double, 3> hr = (rmax - rmin) / ippl::Vector<double, 3>(
nr);
30 std::array<bool, 3> decomp = {
true,
true,
true};
32 ippl::NDIndex<3> domain;
33 for (
unsigned i = 0; i < 3; i++) {
34 domain[i] = ippl::Index(this->
nr[i]);
38 auto fc = std::make_shared<FieldContainer_t>(
46 pc = std::make_shared<ParticleContainer<double, 3>>(mesh, fl);
56 std::shared_ptr<ParticleContainer<double, 3>>
pc;
58 ippl::Vector<int, 3>
nr;
62template <
typename ViewType>
63void computeMean(ViewType& view,
size_t nlocal,
size_t total_nparticles,
double meanR[3]) {
64 double sumR[3] = {0.0, 0.0, 0.0};
66 Kokkos::parallel_reduce(
68 KOKKOS_LAMBDA(
const int k,
double& cent0,
double& cent1,
double& cent2) {
73 Kokkos::Sum<double>(sumR[0]), Kokkos::Sum<double>(sumR[1]),
74 Kokkos::Sum<double>(sumR[2]));
77 MPI_Allreduce(sumR, meanR, 3, MPI_DOUBLE, MPI_SUM, ippl::Comm->getCommunicator());
78 ippl::Comm->barrier();
80 for (
int i = 0; i < 3; i++)
81 meanR[i] /= total_nparticles;
84template <
typename ViewType>
86 ViewType& view,
size_t nlocal,
size_t total_nparticles,
const double meanR[3],
88 double sumR2[3] = {0.0, 0.0, 0.0};
91 Kokkos::parallel_reduce(
93 KOKKOS_LAMBDA(
const int k,
double& s0,
double& s1,
double& s2) {
94 s0 += view(k)[0] * view(k)[0];
95 s1 += view(k)[1] * view(k)[1];
96 s2 += view(k)[2] * view(k)[2];
98 Kokkos::Sum<double>(sumR2[0]), Kokkos::Sum<double>(sumR2[1]),
99 Kokkos::Sum<double>(sumR2[2]));
103 double global_sumR2[3] = {0.0, 0.0, 0.0};
104 MPI_Allreduce(sumR2, global_sumR2, 3, MPI_DOUBLE, MPI_SUM, ippl::Comm->getCommunicator());
105 ippl::Comm->barrier();
108 for (
int i = 0; i < 3; i++) {
109 double mean_square = global_sumR2[i] /
static_cast<double>(total_nparticles);
110 double variance = mean_square - meanR[i] * meanR[i];
111 stddevR[i] = std::sqrt(variance);
115template <
typename ViewType>
117 ViewType& view,
size_t nlocal,
double global_maxAbsR[3],
double& global_maxRadius) {
119 double local_maxAbsR[3] = {0.0, 0.0, 0.0};
120 double local_maxRadius = 0.0;
123 Kokkos::parallel_reduce(
125 KOKKOS_LAMBDA(
const int k,
double& max0,
double& max1,
double& max2,
double& maxr) {
126 double x = view(k)[0];
127 double y = view(k)[1];
128 double z = view(k)[2];
130 double ax = Kokkos::fabs(x);
131 double ay = Kokkos::fabs(y);
132 double az = Kokkos::fabs(z);
133 double r = Kokkos::sqrt(x * x + y * y + z * z);
135 if (ax > max0) max0 = ax;
136 if (ay > max1) max1 = ay;
137 if (az > max2) max2 = az;
138 if (r > maxr) maxr = r;
140 Kokkos::Max<double>(local_maxAbsR[0]), Kokkos::Max<double>(local_maxAbsR[1]),
141 Kokkos::Max<double>(local_maxAbsR[2]), Kokkos::Max<double>(local_maxRadius));
146 local_maxAbsR, global_maxAbsR, 3, MPI_DOUBLE, MPI_MAX, ippl::Comm->getCommunicator());
148 &local_maxRadius, &global_maxRadius, 1, MPI_DOUBLE, MPI_MAX,
149 ippl::Comm->getCommunicator());
151 ippl::Comm->barrier();
156static void preallocateParticleCapacity(
158 const int nranks = std::max(1, ippl::Comm->size());
159 const size_t nranksU =
static_cast<size_t>(nranks);
162 const size_t maxLocalNum = totalParticles / nranksU + 2 * nranksU + 1;
164 pc->allocateParticles(maxLocalNum);
173 Gaussian sampler(pc, sigmaR_ref, sigmaP_ref, avrgpz, cutoffR);
175 size_t total_nparticles = 100000;
177 preallocateParticleCapacity(pc, total_nparticles);
180 auto Rview = pc->R.getView();
181 auto Pview = pc->P.getView();
184 double meanR[3] = {0.0, 0.0, 0.0};
185 computeMean(Rview, pc->getLocalNum(), total_nparticles, meanR);
187 EXPECT_NEAR(meanR[0], 0.0, 1e-15);
188 EXPECT_NEAR(meanR[1], 0.0, 1e-15);
189 EXPECT_NEAR(meanR[2], 0.0, 1e-15);
192 double sigmaR[3] = {0.0, 0.0, 0.0};
193 computeStdDev(Rview, pc->getLocalNum(), total_nparticles, meanR, sigmaR);
195 EXPECT_NEAR(sigmaR[0], sigmaR_ref[0], 1e-2);
196 EXPECT_NEAR(sigmaR[1], sigmaR_ref[1], 1e-2);
197 EXPECT_NEAR(sigmaR[2], sigmaR_ref[2], 1e-2);
206 bool fixMeanR =
false;
207 Gaussian sampler(pc, sigmaR, sigmaP, avrgpz, cutoffR, fixMeanR);
209 size_t total_nparticles = 100000;
211 preallocateParticleCapacity(pc, total_nparticles);
214 auto Rview = pc->R.getView();
217 double global_maxAbsR[3] = {0.0, 0.0, 0.0};
218 double global_maxRadius = 0.0;
219 computeMaxAbsR(Rview, pc->getLocalNum(), global_maxAbsR, global_maxRadius);
224 EXPECT_LE(global_maxAbsR[0], cutoffR[0]);
225 EXPECT_LE(global_maxAbsR[1], cutoffR[1]);
226 EXPECT_LE(global_maxAbsR[2], cutoffR[2]);
235 Gaussian sampler(pc, sigmaR_ref, sigmaP_ref, avrgpz, cutoffR);
237 size_t total_nparticles = 100000;
238 preallocateParticleCapacity(pc, total_nparticles);
241 auto Pview = pc->P.getView();
246 double meanP[3] = {0.0, 0.0, 0.0};
248 computeMean(Pview, pc->getLocalNum(), total_nparticles, meanP);
253 double sigmaP[3] = {0.0, 0.0, 0.0};
254 computeStdDev(Pview, pc->getLocalNum(), total_nparticles, meanP, sigmaP);
259 EXPECT_NEAR(meanP[0], 0.0, 1e-2);
260 EXPECT_NEAR(meanP[1], 0.0, 1e-2);
261 EXPECT_NEAR(meanP[2], avrgpz, 1e-2);
263 EXPECT_NEAR(sigmaP[0], sigmaP_ref[0], 1e-2);
264 EXPECT_NEAR(sigmaP[1], sigmaP_ref[1], 1e-2);
265 EXPECT_NEAR(sigmaP[2], sigmaP_ref[2], 1e-2);
ippl::Vector< T, Dim > Vector_t
ippl::FieldLayout< Dim > FieldLayout_t
ippl::UniformCartesian< double, 3 > Mesh_t
void computeStdDev(ViewType &view, size_t nlocal, size_t total_nparticles, const double meanR[3], double stddevR[3])
void computeMean(ViewType &view, size_t nlocal, size_t total_nparticles, double meanR[3])
void computeMaxAbsR(ViewType &view, size_t nlocal, double global_maxAbsR[3], double &global_maxRadius)
TEST_F(GaussianTest, meanR_stddevR)
std::shared_ptr< BunchStateHandler > bunchStateHandler
static void SetUpTestSuite()
ippl::Vector< int, 3 > nr
static void TearDownTestSuite()
std::shared_ptr< ParticleContainer< double, 3 > > pc
Generating particles following a Gaussian distribution.
void generateParticles(size_t &numberOfParticles, Vector_t< double, 3 > nr) override
Generates particles with a Gaussian distribution.
Container for all per-particle (and per-simulation) fields tracked during OPALX tracking.