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;
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);
128 pc, meanR_ref, meanP_ref, sigmaR_ref, sigmaP_ref, cutoffR_ref, cutoffP_ref);
130 size_t total_nparticles = 100000;
132 preallocateParticleCapacity(pc, total_nparticles);
136 computeMean(pc->R.getView(), pc->getLocalNum(), total_nparticles, meanR);
138 EXPECT_NEAR(meanR[0], meanR_ref[0], 1e-15);
139 EXPECT_NEAR(meanR[1], meanR_ref[1], 1e-15);
140 EXPECT_NEAR(meanR[2], meanR_ref[2], 1e-15);
144 computeStdDev(pc->R.getView(), pc->getLocalNum(), total_nparticles, meanR, stddevR);
146 EXPECT_NEAR(stddevR[0], sigmaR_ref[0], 1e-2);
147 EXPECT_NEAR(stddevR[1], sigmaR_ref[1], 1e-2);
148 EXPECT_NEAR(stddevR[2], sigmaR_ref[2], 1e-2);
153 ViewType view,
size_t nlocal,
double global_maxAbsR[3],
double& global_maxRadius) {
155 double local_maxAbsR[3] = {0.0, 0.0, 0.0};
156 double local_maxRadius = 0.0;
159 Kokkos::parallel_reduce(
161 KOKKOS_LAMBDA(
const int k,
double& max0,
double& max1,
double& max2,
double& maxr) {
162 double x = view(k)[0];
163 double y = view(k)[1];
164 double z = view(k)[2];
166 double ax = Kokkos::fabs(x);
167 double ay = Kokkos::fabs(y);
168 double az = Kokkos::fabs(z);
169 double r = Kokkos::sqrt(x * x + y * y + z * z);
171 if (ax > max0) max0 = ax;
172 if (ay > max1) max1 = ay;
173 if (az > max2) max2 = az;
174 if (r > maxr) maxr = r;
176 Kokkos::Max<double>(local_maxAbsR[0]), Kokkos::Max<double>(local_maxAbsR[1]),
177 Kokkos::Max<double>(local_maxAbsR[2]), Kokkos::Max<double>(local_maxRadius));
182 local_maxAbsR, global_maxAbsR, 3, MPI_DOUBLE, MPI_MAX, ippl::Comm->getCommunicator());
184 &local_maxRadius, &global_maxRadius, 1, MPI_DOUBLE, MPI_MAX,
185 ippl::Comm->getCommunicator());
187 ippl::Comm->barrier();
210 bool fixMeanR =
false;
211 bool fixMeanP =
false;
213 pc, meanR_ref, meanP_ref, sigmaR_ref, sigmaP_ref, cutoffR_ref, cutoffP_ref, fixMeanR,
216 size_t total_nparticles = 100000;
217 preallocateParticleCapacity(pc, total_nparticles);
220 double global_maxAbsR[3];
221 double global_maxRadius;
222 computeMaxAbsR(pc->R.getView(), pc->getLocalNum(), global_maxAbsR, global_maxRadius);
225 EXPECT_LE(global_maxAbsR[0], cutoffR_ref[0]);
226 EXPECT_LE(global_maxAbsR[1], cutoffR_ref[1]);
227 EXPECT_LE(global_maxAbsR[2], cutoffR_ref[2]);
237 bool fixMeanR =
true;
238 bool fixMeanP =
true;
241 pc, meanR_ref, meanP_ref, sigmaR_ref, sigmaP_ref, cutoffR_ref, cutoffP_ref, fixMeanR,
244 size_t total_nparticles = 100000;
245 preallocateParticleCapacity(pc, total_nparticles);
248 double meanP[3] = {0.0, 0.0, 0.0};
249 computeMean(pc->P.getView(), pc->getLocalNum(), total_nparticles, meanP);
251 double sigmaP[3] = {0.0, 0.0, 0.0};
252 computeStdDev(pc->P.getView(), pc->getLocalNum(), total_nparticles, meanP, sigmaP);
254 EXPECT_NEAR(meanP[0], meanP_ref[0], 1e-2);
255 EXPECT_NEAR(meanP[1], meanP_ref[1], 1e-2);
256 EXPECT_NEAR(meanP[2], meanP_ref[2], 1e-2);
258 EXPECT_NEAR(sigmaP[0], sigmaP_ref[0], 1e-2);
259 EXPECT_NEAR(sigmaP[1], sigmaP_ref[1], 1e-2);
260 EXPECT_NEAR(sigmaP[2], sigmaP_ref[2], 1e-2);
265 double meanSample[6]) {
266 auto Rview = pc->R.getView();
267 auto Pview = pc->P.getView();
269 double loc_sum[6] = {0.0};
273 Kokkos::parallel_reduce(
276 const int k,
double& s0,
double& s1,
double& s2,
double& s3,
double& s4,
285 Kokkos::Sum<double>(loc_sum[0]), Kokkos::Sum<double>(loc_sum[1]),
286 Kokkos::Sum<double>(loc_sum[2]), Kokkos::Sum<double>(loc_sum[3]),
287 Kokkos::Sum<double>(loc_sum[4]), Kokkos::Sum<double>(loc_sum[5]));
291 double global_sum[6] = {0.0};
292 MPI_Allreduce(loc_sum, global_sum, 6, MPI_DOUBLE, MPI_SUM, ippl::Comm->getCommunicator());
293 ippl::Comm->barrier();
296 for (
int i = 0; i < 6; i++)
297 meanSample[i] = global_sum[i] /
static_cast<double>(total_nparticles);
302 size_t total_nparticles,
double moment[6][6]) {
303 auto Rview = pc->R.getView();
304 auto Pview = pc->P.getView();
306 Kokkos::Array<double, 6> mean = {meanSample[0], meanSample[1], meanSample[2],
307 meanSample[3], meanSample[4], meanSample[5]};
309 double loc_moment[6][6] = {{0.0}};
311 for (
unsigned i = 0; i < 6; ++i) {
312 const unsigned row = i;
313 Kokkos::parallel_reduce(
316 const int k,
double& s0,
double& s1,
double& s2,
double& s3,
double& s4,
318 double part[6] = {Rview(k)[0] - mean[0], Pview(k)[0] - mean[1],
319 Rview(k)[1] - mean[2], Pview(k)[1] - mean[3],
320 Rview(k)[2] - mean[4], Pview(k)[2] - mean[5]};
321 s0 += part[row] * part[0];
322 s1 += part[row] * part[1];
323 s2 += part[row] * part[2];
324 s3 += part[row] * part[3];
325 s4 += part[row] * part[4];
326 s5 += part[row] * part[5];
328 Kokkos::Sum<double>(loc_moment[row][0]), Kokkos::Sum<double>(loc_moment[row][1]),
329 Kokkos::Sum<double>(loc_moment[row][2]), Kokkos::Sum<double>(loc_moment[row][3]),
330 Kokkos::Sum<double>(loc_moment[row][4]), Kokkos::Sum<double>(loc_moment[row][5]));
335 MPI_Allreduce(loc_moment, moment, 6 * 6, MPI_DOUBLE, MPI_SUM, ippl::Comm->getCommunicator());
336 ippl::Comm->barrier();
339 for (
unsigned i = 0; i < 6; ++i) {
340 for (
unsigned j = 0; j < 6; ++j) {
341 moment[i][j] /=
static_cast<double>(total_nparticles);
356 using matrix_t = ippl::Vector<ippl::Vector<double, 6>, 6>;
360 for (
int i = 0; i < 6; i++) {
361 for (
int j = 0; j < 6; j++) {
363 covExpected[i][j] = 0.0;
368 for (
int i = 0; i < 3; i++) {
369 L[i * 2][i * 2] = sigmaR[i];
370 L[i * 2 + 1][i * 2 + 1] = sigmaP[i];
374 for (
int i = 0; i < 6; i++) {
375 for (
int j = 0; j < i; j++) {
376 L[i][j] = (i + j + 1) * 0.1;
382 for (
int i = 0; i < 6; i++) {
383 for (
int j = 0; j < 6; j++) {
385 for (
int k = 0; k < 6; k++)
386 sum += L[i][k] * L[j][k];
387 covExpected[i][j] = sum;
397 size_t total_nparticles = 1000000;
398 preallocateParticleCapacity(pc, total_nparticles);
401 double meanSample[6];
405 EXPECT_NEAR(meanSample[0], meanR[0], 5e-3);
406 EXPECT_NEAR(meanSample[1], meanP[0], 5e-3);
407 EXPECT_NEAR(meanSample[2], meanR[1], 5e-3);
408 EXPECT_NEAR(meanSample[3], meanP[1], 5e-3);
409 EXPECT_NEAR(meanSample[4], meanR[2], 5e-3);
410 EXPECT_NEAR(meanSample[5], meanP[2], 5e-3);
421 for (
int i = 0; i < 6; i++) {
422 for (
int j = 0; j < 6; j++) {
423 EXPECT_NEAR(moment[i][j], covExpected[i][j], 3e-2);
Container for all per-particle (and per-simulation) fields tracked during OPALX tracking.