46 ippl::ParticleAttrib<double>::view_type Mview,
size_t Np,
size_t Nlocal) {
54 Np = (Np == 0) ? 1 : Np;
63 const bool massIsScalarView = (Mview.extent(0) == 1);
70 Kokkos::parallel_reduce(
71 "computeMeans", Nlocal,
73 upd.
data[0] += Rview(k)[0];
74 upd.
data[1] += Pview(k)[0];
75 upd.
data[2] += Rview(k)[1];
76 upd.
data[3] += Pview(k)[1];
77 upd.
data[4] += Rview(k)[2];
78 upd.
data[5] += Pview(k)[2];
80 double gamma0 = Kokkos::sqrt(
dot(Pview(k)) + 1.0);
82 const double massGeV = rescaleToReference
84 : (massIsScalarView ? Mview(0) : Mview(k));
86 upd.
data[7] += gamma0;
88 Kokkos::Sum<SumArray<8>>(loc));
92 ippl::Comm->allreduce(&loc.
data[0], &glob[0], 8, std::plus<double>());
94 for (
size_t i = 0; i < 2 *
Dim; ++i) {
103 double gammaz = glob[5] / (1. * Np);
104 gammaz = std::sqrt(gammaz * gammaz + 1.0);
107 for (
size_t i = 0; i <
Dim; ++i) {
121 ippl::ParticleAttrib<double>::view_type Mview,
size_t Np,
size_t Nlocal) {
127 "DistributionMoments::computeMoments",
128 "ContainerState not available (expired or never bound). "
129 "Did you forget setContainerState(), or did the owning "
130 "ParticleContainer outlive its slot?");
138 if (!slot->momentsDirty) {
142 Np = (Np == 0) ? 1 : Np;
145 IpplTimings::TimerRef momentsTimer = IpplTimings::getTimer(
"computeMoments");
146 IpplTimings::startTimer(momentsTimer);
151 double meanR_loc[
Dim];
152 double meanP_loc[
Dim];
153 for (
size_t i = 0; i <
Dim; ++i) {
161 const bool massIsScalarView = (Mview.extent(0) == 1);
165 double loc_std_ekin = 0.0;
167 Kokkos::parallel_reduce(
168 "computeMoments", Nlocal,
173 cent[0] = Rview(k)[0] - meanR_loc[0];
174 cent[1] = Pview(k)[0] - meanP_loc[0];
175 cent[2] = Rview(k)[1] - meanR_loc[1];
176 cent[3] = Pview(k)[1] - meanP_loc[1];
177 cent[4] = Rview(k)[2] - meanR_loc[2];
178 cent[5] = Pview(k)[2] - meanP_loc[2];
181 raw[0] = Rview(k)[0];
182 raw[1] = Pview(k)[0];
183 raw[2] = Rview(k)[1];
184 raw[3] = Pview(k)[1];
185 raw[4] = Rview(k)[2];
186 raw[5] = Pview(k)[2];
188 for (
size_t i = 0; i < 6; ++i) {
189 for (
size_t j = 0; j < 6; ++j) {
190 cent_upd.
data[i][j] += cent[i] * cent[j];
191 ncent_upd.
data[i][j] += raw[i] * raw[j];
195 double gamma0 = Kokkos::sqrt(
dot(Pview(k)) + 1.0);
196 const double massGeV = rescaleToReferenceStd
197 ? referenceMassGeVStd
198 : (massIsScalarView ? Mview(0) : Mview(k));
200 ekin_upd += (ekin0 - mekin) * (ekin0 - mekin);
202 Kokkos::Sum<SumMatrix6x6>(loc_cent), Kokkos::Sum<SumMatrix6x6>(loc_ncent),
203 Kokkos::Sum<double>(loc_std_ekin));
206 ippl::Comm->allreduce(&loc_cent.
data[0][0], &glob_cent.data[0][0], 36, std::plus<double>());
207 ippl::Comm->allreduce(&loc_ncent.
data[0][0], &glob_ncent.data[0][0], 36, std::plus<double>());
209 double glob_std_ekin;
210 ippl::Comm->allreduce(&loc_std_ekin, &glob_std_ekin, 1, std::plus<double>());
212 for (
size_t i = 0; i < 2 *
Dim; ++i) {
213 for (
size_t j = 0; j < 2 *
Dim; ++j) {
214 moments_m(i, j) = glob_cent.data[i][j] / Np;
219 for (
size_t i = 0; i <
Dim; ++i) {
226 double perParticle = 1. / (1. * Np);
229 for (
size_t i = 0; i < 3; ++i, l += 2) {
234 double tmp = w2 - std::pow(w1, 2);
236 halo_m(i) = (w4 + w1 * (-4 * w3 + 3 * w1 * (tmp + w2))) / tmp;
240 for (
size_t i = 0; i < 3; ++i) {
243 squaredEps(i) = std::pow(
stdR_m(i) *
stdP_m(i), 2) - std::pow(sumRP(i), 2);
247 double betaGamma = std::sqrt(std::pow(
meanGamma_m, 2) - 1.0);
250 slot->markMomentsClean();
251 IpplTimings::stopTimer(momentsTimer);
261 Inform m(
"DistributionMoments::computeMinMaxPosition");
265 Kokkos::parallel_reduce(
266 "computeMinMaxPosition", Nlocal,
268 for (
size_t d = 0; d < 3; ++d) {
269 const double r = Rview(k)[d];
270 if (r > rmax.
data[d]) rmax.
data[d] = r;
271 if (r < rmin.
data[d]) rmin.
data[d] = r;
274 Kokkos::Sum<MaxArray<3>>(loc_max), Kokkos::Sum<
MinArray<3>>(loc_min));
276 double rmax[
Dim], rmin[
Dim];
277 ippl::Comm->allreduce(&loc_max.
data[0], &rmax[0],
Dim, std::greater<double>());
278 ippl::Comm->allreduce(&loc_min.
data[0], &rmin[0],
Dim, std::less<double>());
284 for (
size_t i = 0; i <
Dim; ++i) {
285 if (rmin[i] > rmax[i]) {
286 rmin[i] = rmax[i] = 0.0;
287 m << level5 <<
"Min > max in dimension " << i <<
". Setting to 0 (degenerate case)."
292 for (
size_t i = 0; i <
Dim; ++i) {
296 m << level5 <<
"Min/max computation done." << endl;
302 const std::vector<OpalParticle>::const_iterator& ,
303 const std::vector<OpalParticle>::const_iterator& ) {
305 "DistributionMoments::compute",
"OpalParticle-iterator interface is not implemented.");
308template <
class InputIt>
314 std::vector<gsl_histogram*> histograms(3);
321 for (
size_t d = 0; d < 3; ++d) {
326 for (InputIt it = first; it != last; ++it) {
328 for (
size_t d = 0; d < 3; ++d) {
333 std::vector<int> localHistogramValues(3 * (numBins + 1)),
334 globalHistogramValues(3 * (numBins + 1));
335 for (
size_t d = 0; d < 3; ++d) {
337 size_t accumulated = 0;
339 localHistogramValues.begin() + d * (numBins + 1) + 1,
340 localHistogramValues.begin() + (d + 1) * (numBins + 1),
341 [&histograms, &d, &j, &accumulated]() {
342 accumulated += gsl_histogram_get(histograms[d], j++);
349 ippl::Comm->allreduce(
350 localHistogramValues.data(), globalHistogramValues.data(), 3 * (numBins + 1),
353 int numParticles68 =
static_cast<int>(
355 int numParticles95 =
static_cast<int>(
357 int numParticles99 =
static_cast<int>(
359 int numParticles99_99 =
static_cast<int>(
362 for (
int d = 0; d < 3; ++d) {
363 unsigned int localNum = last - first, current = 0;
364 std::vector<Vector_t<double, 2>> oneDPhaseSpace(localNum);
365 for (InputIt it = first; it != last; ++it, ++current) {
367 oneDPhaseSpace[current](0) = particle[2 * d];
368 oneDPhaseSpace[current](1) = particle[2 * d + 1];
371 oneDPhaseSpace.begin(), oneDPhaseSpace.end(),
373 return std::abs(left[0] - meanR_m[d]) < std::abs(right[0] - meanR_m[d]);
376 iterator_t endSixtyEight, endNinetyFive, endNinetyNine, endNinetyNine_NinetyNine;
377 endSixtyEight = endNinetyFive = endNinetyNine = endNinetyNine_NinetyNine =
378 oneDPhaseSpace.end();
381 oneDPhaseSpace.begin(), oneDPhaseSpace.end(), globalHistogramValues,
382 localHistogramValues, d, numParticles68);
385 oneDPhaseSpace.begin(), oneDPhaseSpace.end(), globalHistogramValues,
386 localHistogramValues, d, numParticles95);
389 oneDPhaseSpace.begin(), oneDPhaseSpace.end(), globalHistogramValues,
390 localHistogramValues, d, numParticles99);
394 oneDPhaseSpace.begin(), oneDPhaseSpace.end(), globalHistogramValues,
395 localHistogramValues, d, numParticles99_99);
440 const std::vector<int>& globalAccumulatedHistogram,
441 const std::vector<int>& localAccumulatedHistogram,
unsigned int dimension,
442 int numRequiredParticles)
const {
443 unsigned int numBins = globalAccumulatedHistogram.size() / 3;
444 double percentile = 0.0;
446 for (
unsigned int i = 1; i < numBins; ++i) {
447 unsigned int idx = dimension * numBins + i;
448 if (globalAccumulatedHistogram[idx] > numRequiredParticles) {
449 iterator_t beginBin = begin + localAccumulatedHistogram[idx - 1];
450 iterator_t endBin = begin + localAccumulatedHistogram[idx];
451 unsigned int numMissingParticles =
452 numRequiredParticles - globalAccumulatedHistogram[idx - 1];
453 unsigned int shift = 2;
454 while (numMissingParticles == 0) {
455 beginBin = begin + localAccumulatedHistogram[idx - shift];
456 numMissingParticles =
457 numRequiredParticles - globalAccumulatedHistogram[idx - shift];
461 std::vector<unsigned int> numParticlesInBin(ippl::Comm->size() + 1);
462 numParticlesInBin[ippl::Comm->rank() + 1] = endBin - beginBin;
464 ippl::Comm->allreduce(
465 &(numParticlesInBin[1]), ippl::Comm->size(), std::plus<unsigned int>());
468 numParticlesInBin.begin(), numParticlesInBin.end(), numParticlesInBin.begin());
470 std::vector<double> positions(numParticlesInBin.back());
472 beginBin, endBin, positions.begin() + numParticlesInBin[ippl::Comm->rank()],
474 return std::abs(particle[0] - meanR_m[dimension]);
476 ippl::Comm->allreduce(&(positions[0]), positions.size(), std::plus<double>());
477 std::sort(positions.begin(), positions.end());
479 percentile = (*(positions.begin() + numMissingParticles - 1)
480 + *(positions.begin() + numMissingParticles))
482 for (
iterator_t it = beginBin; it != endBin; ++it) {
483 if (std::abs((*it)[0] -
meanR_m[dimension]) > percentile) {
484 return std::make_pair(percentile, it);
487 endPercentile = endBin;
491 return std::make_pair(percentile, endPercentile);
497 double localStatistics[] = {0.0, 0.0, 0.0, 0.0};
498 localStatistics[0] = end - begin;
501 localStatistics[1] += rp(0);
502 localStatistics[2] += rp(1);
503 localStatistics[3] += rp(0) * rp(1);
505 ippl::Comm->allreduce(&(localStatistics[0]), 4, std::plus<double>());
507 double numParticles = localStatistics[0];
508 double perParticle = 1 / localStatistics[0];
509 double meanR = localStatistics[1] * perParticle;
510 double meanP = localStatistics[2] * perParticle;
511 double RP = localStatistics[3] * perParticle;
513 localStatistics[0] = 0.0;
514 localStatistics[1] = 0.0;
517 localStatistics[0] += std::pow(rp(0) - meanR, 2);
518 localStatistics[1] += std::pow(rp(1) - meanP, 2);
520 ippl::Comm->allreduce(&(localStatistics[0]), 2, std::plus<double>());
522 double stdR = std::sqrt(localStatistics[0] / numParticles);
523 double stdP = std::sqrt(localStatistics[1] / numParticles);
524 double sumRP = RP - meanR * meanP;
525 double squaredEps = std::pow(stdR * stdP, 2) - std::pow(sumRP, 2);
526 double normalizedEps = std::sqrt(std::max(squaredEps, 0.0));
528 return normalizedEps;
535 "DistributionMoments::fillMembers",
"Not implemented -- must not be called.");
540 "DistributionMoments::computeMeanKineticEnergy",
541 "Not implemented -- must not be called.");
550 Np = (Np == 0) ? 1 : Np;
557 Kokkos::parallel_reduce(
558 "computeDebyeLength avgVel", Nlocal,
560 double gamma0 = Kokkos::sqrt(
dot(Pview(k)) + 1.0);
562 upd.
data[0] += Pview(k)[0] * c / gamma0;
563 upd.
data[1] += Pview(k)[1] * c / gamma0;
564 upd.
data[2] += Pview(k)[2] * c / gamma0;
566 Kokkos::Sum<SumArray<3>>(loc_vel));
570 ippl::Comm->allreduce(&loc_vel.
data[0], &avgVel[0],
Dim, std::plus<double>());
572 for (
unsigned i = 0; i < 3; ++i)
575 double loc_tempAvg = 0.0;
576 Kokkos::parallel_reduce(
577 "computeDebyeLength temperature", Nlocal,
578 KOKKOS_LAMBDA(
const size_t k,
double& mom0) {
579 double gamma0 = Kokkos::sqrt(
dot(Pview(k)) + 1.0);
581 mom0 += Kokkos::pow(Pview(k)[0] * c / gamma0 - avgVel[0], 2);
582 mom0 += Kokkos::pow(Pview(k)[1] * c / gamma0 - avgVel[1], 2);
583 mom0 += Kokkos::pow(Pview(k)[2] * c / gamma0 - avgVel[2], 2);
585 Kokkos::Sum<double>(loc_tempAvg));
589 ippl::Comm->allreduce(&loc_tempAvg, &tempAvg, 1, std::plus<double>());
642 "DistributionMoments::isParticleExcluded",
"Not implemented -- must not be called.");
ippl::Vector< T, Dim > Vector_t
typename ippl::detail::ViewType< ippl::Vector< double, Dim >, 1 >::view_type view_type
void gsl_histogram_free(gsl_histogram *h)
Free a histogram allocated by gsl_histogram_alloc.
void gsl_histogram_increment(gsl_histogram *h, double x)
Increment the bin containing x by 1.
void gsl_histogram_set_ranges_uniform(gsl_histogram *h, double xmin, double xmax)
Set uniform bin edges over .
gsl_histogram * gsl_histogram_alloc(size_t n)
Allocate a 1D histogram with n bins.
matrix_t< 6, 6 > matrix6x6_t
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
double meanKineticEnergy_m
void fillMembers(std::vector< double > &)
Vector_t< double, 3 > sixtyEightPercentile_m
bool rescaleToReference_m
Vector_t< double, 3 > ninetyFivePercentile_m
void computeDebyeLength(ippl::ParticleAttrib< Vector_t< double, 3 > >::view_type Pview, size_t Np, size_t Nlocal, double density)
void computePlasmaParameter(double)
std::vector< Vector_t< double, 2 > >::const_iterator iterator_t
Vector_t< double, 3 > minR_m
static const double percentileFourSigmasNormalDist_m
void computeMoments(ippl::ParticleAttrib< Vector_t< double, 3 > >::view_type Rview, ippl::ParticleAttrib< Vector_t< double, 3 > >::view_type Pview, ippl::ParticleAttrib< double >::view_type Mview, size_t Np, size_t Nlocal)
unsigned int totalNumParticles_m
matrix6x6_t notCentMoments_m
void computeMeans(ippl::ParticleAttrib< Vector_t< double, 3 > >::view_type Rview, ippl::ParticleAttrib< Vector_t< double, 3 > >::view_type Pview, ippl::ParticleAttrib< double >::view_type Mview, size_t Np, size_t Nlocal)
void computeMinMaxPosition(ippl::ParticleAttrib< Vector_t< double, 3 > >::view_type Rview, size_t Nlcoal)
Vector_t< double, 3 > ninetyNinePercentile_m
void compute(const std::vector< OpalParticle >::const_iterator &, const std::vector< OpalParticle >::const_iterator &)
Vector_t< double, 3 > ninetyNine_NinetyNinePercentile_m
Vector_t< double, 3 > normalizedEps_m
Vector_t< double, 3 > normalizedEps68Percentile_m
Vector_t< double, 3 > meanP_m
double computeNormalizedEmittance(const iterator_t &begin, const iterator_t &end) const
Vector_t< double, 3 > halo_m
Vector_t< double, 3 > stdP_m
Vector_t< double, 3 > normalizedEps99Percentile_m
Vector_t< double, 3 > stdR_m
static const double percentileThreeSigmasNormalDist_m
Vector_t< double, 3 > meanR_m
void computePercentiles(const InputIt &, const InputIt &)
static const double percentileTwoSigmasNormalDist_m
double referenceMassGeV_m
Vector_t< double, 3 > normalizedEps99_99Percentile_m
void computeMeanKineticEnergy()
bool isParticleExcluded(const OpalParticle &) const
std::weak_ptr< BunchStateHandler::ContainerState > containerState_m
Vector_t< double, 3 > maxR_m
Vector_t< double, 3 > stdRP_m
std::pair< double, iterator_t > determinePercentilesDetail(const iterator_t &begin, const iterator_t &end, const std::vector< int > &globalAccumulatedHistogram, const std::vector< int > &localAccumulatedHistogram, unsigned int dimension, int numRequiredParticles) const
Vector_t< double, 3 > geometricEps_m
static const double percentileOneSigmaNormalDist_m
void resetPlasmaParameters()
Vector_t< double, 6 > means_m
Vector_t< double, 6 > centroid_m
double stdKineticEnergy_m
Vector_t< double, 3 > normalizedEps95Percentile_m
double haloShift
The constant parameter C to shift halo, by < w^4 > / < w^2 > ^2 - C (w=x,y,z)
constexpr double epsilon_0
The permittivity of vacuum in As/Vm.
constexpr double q_e
The elementary charge in As.
constexpr double m_e
The electron rest mass in GeV.
constexpr double c
The velocity of light in m/s.
constexpr double pi
The value of.