24#include "Utility/Inform.h"
28#include <gsl/gsl_histogram.h>
30#include <boost/numeric/conversion/cast.hpp>
49 ippl::ParticleAttrib<double>::view_type& Mview,
59 Np = (Np == 0) ? 1 : Np;
62 double loc_centroid[2 *
Dim] = {};
63 double centroid[2 *
Dim] = {};
64 double loc_Ekin, loc_gamma, loc_gammaz, gammaz;
67 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
69 Kokkos::parallel_reduce(
70 "calc moments of particle distr.", Nlocal,
72 const int k,
double& ekin,
double& gamma,
double& gammaz) {
76 for(
unsigned j=0; j<
Dim; j++){
77 gamma0 += Pview(k)[j]*Pview(k)[j];
79 gamma0 = Kokkos::sqrt(gamma0+1.0);
80 ekin0 = (gamma0-1.0) * Mview(k);
84 gammaz += Pview(k)[2];
86 Kokkos::Sum<double>(loc_Ekin), Kokkos::Sum<double>(loc_gamma), Kokkos::Sum<double>(loc_gammaz));
89 for (
unsigned i = 0; i < 2 *
Dim; ++i) {
90 Kokkos::parallel_reduce(
91 "calc moments of particle distr.", Nlocal,
93 const int k,
double& cent) {
95 part[0] = Rview(k)[0];
96 part[1] = Pview(k)[0];
97 part[2] = Rview(k)[1];
98 part[3] = Pview(k)[1];
99 part[4] = Rview(k)[2];
100 part[5] = Pview(k)[2];
104 Kokkos::Sum<double>(loc_centroid[i]));
107 ippl::Comm->barrier();
110 loc_centroid, centroid, 2 *
Dim, MPI_DOUBLE, MPI_SUM, ippl::Comm->getCommunicator());
114 &loc_gamma, &
meanGamma_m, 1, MPI_DOUBLE, MPI_SUM, ippl::Comm->getCommunicator());
116 &loc_gammaz, &gammaz, 1, MPI_DOUBLE, MPI_SUM, ippl::Comm->getCommunicator());
118 for (
unsigned i = 0; i < 2 *
Dim; i++) {
125 gammaz = gammaz / (1.*Np);
127 gammaz = std::sqrt(gammaz + 1.0);
131 for (
unsigned i = 0; i <
Dim; i++) {
138 ippl::ParticleAttrib<double>::view_type& Mview,
141 Np = (Np == 0) ? 1 : Np;
146 double meanR_loc[
Dim] = {};
147 double meanP_loc[
Dim] = {};
148 double loc_moment[2 *
Dim][2 *
Dim] = {};
149 double moment[2 *
Dim][2 *
Dim] = {};
151 double loc_moment_ncent[2 *
Dim][2 *
Dim] = {};
152 double moment_ncent[2 *
Dim][2 *
Dim] = {};
155 for (
unsigned i = 0; i <
Dim; i++) {
160 for (
unsigned i = 0; i < 2 *
Dim; ++i) {
161 Kokkos::parallel_reduce(
162 "calc moments of particle distr.", Nlocal,
164 const int k,
double& mom0,
double& mom1,
double& mom2,
165 double& mom3,
double& mom4,
double& mom5) {
166 double part[2 *
Dim];
167 part[0] = Rview(k)[0]-meanR_loc[0];
168 part[1] = Pview(k)[0]-meanP_loc[0];
169 part[2] = Rview(k)[1]-meanR_loc[1];
170 part[3] = Pview(k)[1]-meanP_loc[1];
171 part[4] = Rview(k)[2]-meanR_loc[2];
172 part[5] = Pview(k)[2]-meanP_loc[2];
174 mom0 += part[i] * part[0];
175 mom1 += part[i] * part[1];
176 mom2 += part[i] * part[2];
177 mom3 += part[i] * part[3];
178 mom4 += part[i] * part[4];
179 mom5 += part[i] * part[5];
181 Kokkos::Sum<double>(loc_moment[i][0]),
182 Kokkos::Sum<double>(loc_moment[i][1]), Kokkos::Sum<double>(loc_moment[i][2]),
183 Kokkos::Sum<double>(loc_moment[i][3]), Kokkos::Sum<double>(loc_moment[i][4]),
184 Kokkos::Sum<double>(loc_moment[i][5]));
189 loc_moment, moment, 2 *
Dim * 2 *
Dim, MPI_DOUBLE, MPI_SUM, ippl::Comm->getCommunicator());
191 for (
unsigned i = 0; i < 2 *
Dim; i++) {
192 for (
unsigned j = 0; j < 2 *
Dim; j++) {
197 for (
unsigned i = 0; i <
Dim; i++) {
203 double loc_std_mekin;
206 for (
unsigned i = 0; i < 2 *
Dim; ++i) {
207 Kokkos::parallel_reduce(
208 "calc moments of particle distr.", Nlocal,
210 const int k,
double& mom0,
double& mom1,
double& mom2,
211 double& mom3,
double& mom4,
double& mom5) {
212 double part[2 *
Dim];
213 part[0] = Rview(k)[0];
214 part[1] = Pview(k)[0];
215 part[2] = Rview(k)[1];
216 part[3] = Pview(k)[1];
217 part[4] = Rview(k)[2];
218 part[5] = Pview(k)[2];
220 mom0 += part[i] * part[0];
221 mom1 += part[i] * part[1];
222 mom2 += part[i] * part[2];
223 mom3 += part[i] * part[3];
224 mom4 += part[i] * part[4];
225 mom5 += part[i] * part[5];
227 Kokkos::Sum<double>(loc_moment_ncent[i][0]),
228 Kokkos::Sum<double>(loc_moment_ncent[i][1]), Kokkos::Sum<double>(loc_moment_ncent[i][2]),
229 Kokkos::Sum<double>(loc_moment_ncent[i][3]), Kokkos::Sum<double>(loc_moment_ncent[i][4]),
230 Kokkos::Sum<double>(loc_moment_ncent[i][5]));
233 ippl::Comm->barrier();
235 Kokkos::parallel_reduce(
236 "calc moments of particle distr.", Nlocal,
238 const int k,
double& ekin) {
242 for(
unsigned j=0; j<
Dim; j++){
243 gamma0 += Pview(k)[j]*Pview(k)[j];
245 gamma0 = Kokkos::sqrt(gamma0+1.0);
246 ekin0 = (gamma0-1.0) * Mview(k);
248 ekin += (ekin0-mekin)*(ekin0-mekin);
249 }, Kokkos::Sum<double>(loc_std_mekin) );
253 loc_moment_ncent, moment_ncent, 2 *
Dim * 2 *
Dim, MPI_DOUBLE, MPI_SUM, ippl::Comm->getCommunicator());
256 &loc_std_mekin, &
stdKineticEnergy_m, 1, MPI_DOUBLE, MPI_SUM, ippl::Comm->getCommunicator());
260 for (
unsigned i = 0; i < 2 *
Dim; i++) {
261 for (
unsigned j = 0; j < 2 *
Dim; j++) {
267 double perParticle = 1./(1.*Np);
270 for (
unsigned int i = 0; i < 3; ++ i, l += 2) {
276 double tmp = w2 - std::pow(w1, 2);
278 halo_m(i) = (w4 + w1 * (-4 * w3 + 3 * w1 * (tmp + w2))) / tmp;
286 for (
unsigned int i = 0; i < 3; ++ i) {
289 squaredEps(i) = std::pow(
stdR_m(i) *
stdP_m(i), 2) - std::pow(sumRP(i), 2);
293 double betaGamma = std::sqrt(std::pow(
meanGamma_m, 2) - 1.0);
302 double rmax_loc[
Dim];
303 double rmin_loc[
Dim];
307 for(
int i=0; i<
Dim; i++){
312 for (
unsigned d = 0; d <
Dim; ++d) {
314 Kokkos::parallel_reduce(
316 KOKKOS_LAMBDA(
const int i,
double& mm) {
317 double tmp_vel = Rview(i)[d];
318 mm = tmp_vel > mm ? tmp_vel : mm;
320 Kokkos::Max<double>(rmax_loc[d]));
322 Kokkos::parallel_reduce(
323 "rel min", ippl::getRangePolicy(Rview),
324 KOKKOS_LAMBDA(
const int i,
double& mm) {
325 double tmp_vel = Rview(i)[d];
326 mm = tmp_vel < mm ? tmp_vel : mm;
328 Kokkos::Min<double>(rmin_loc[d]));
332 MPI_Allreduce(rmax_loc, rmax,
Dim, MPI_DOUBLE, MPI_MAX, ippl::Comm->getCommunicator());
333 MPI_Allreduce(rmin_loc, rmin,
Dim, MPI_DOUBLE, MPI_MIN, ippl::Comm->getCommunicator());
334 ippl::Comm->barrier();
337 for (
unsigned int i=0; i<
Dim; i++) {
344 const std::vector<OpalParticle>::const_iterator& first,
345 const std::vector<OpalParticle>::const_iterator& last) {
460template <
class InputIt>
466 std::vector<gsl_histogram*> histograms(3);
473 for (
unsigned int d = 0; d < 3; ++d) {
475 histograms[d] = gsl_histogram_alloc(numBins);
476 gsl_histogram_set_ranges_uniform(histograms[d], 0.0, maxR(d));
478 for (InputIt it = first; it != last; ++it) {
480 for (
unsigned int d = 0; d < 3; ++d) {
481 gsl_histogram_increment(histograms[d], std::abs(particle[2 * d] -
meanR_m[d]));
485 std::vector<int> localHistogramValues(3 * (numBins + 1)),
486 globalHistogramValues(3 * (numBins + 1));
487 for (
unsigned int d = 0; d < 3; ++d) {
489 size_t accumulated = 0;
491 localHistogramValues.begin() + d * (numBins + 1) + 1,
492 localHistogramValues.begin() + (d + 1) * (numBins + 1),
493 [&histograms, &d, &j, &accumulated]() {
494 accumulated += gsl_histogram_get(histograms[d], j++);
498 gsl_histogram_free(histograms[d]);
501 ippl::Comm->allreduce(
502 localHistogramValues.data(), globalHistogramValues.data(), 3 * (numBins + 1),
505 int numParticles68 = boost::numeric_cast<int>(
507 int numParticles95 = boost::numeric_cast<int>(
509 int numParticles99 = boost::numeric_cast<int>(
511 int numParticles99_99 = boost::numeric_cast<int>(
514 for (
int d = 0; d < 3; ++d) {
515 unsigned int localNum = last - first, current = 0;
516 std::vector<Vector_t<double, 2>> oneDPhaseSpace(localNum);
517 for (InputIt it = first; it != last; ++it, ++current) {
519 oneDPhaseSpace[current](0) = particle[2 * d];
520 oneDPhaseSpace[current](1) = particle[2 * d + 1];
523 oneDPhaseSpace.begin(), oneDPhaseSpace.end(),
525 return std::abs(left[0] - meanR_m[d]) < std::abs(right[0] - meanR_m[d]);
528 iterator_t endSixtyEight, endNinetyFive, endNinetyNine, endNinetyNine_NinetyNine;
529 endSixtyEight = endNinetyFive = endNinetyNine = endNinetyNine_NinetyNine =
530 oneDPhaseSpace.end();
533 oneDPhaseSpace.begin(), oneDPhaseSpace.end(), globalHistogramValues,
534 localHistogramValues, d, numParticles68);
537 oneDPhaseSpace.begin(), oneDPhaseSpace.end(), globalHistogramValues,
538 localHistogramValues, d, numParticles95);
541 oneDPhaseSpace.begin(), oneDPhaseSpace.end(), globalHistogramValues,
542 localHistogramValues, d, numParticles99);
546 oneDPhaseSpace.begin(), oneDPhaseSpace.end(), globalHistogramValues,
547 localHistogramValues, d, numParticles99_99);
592 const std::vector<int>& globalAccumulatedHistogram,
593 const std::vector<int>& localAccumulatedHistogram,
unsigned int dimension,
594 int numRequiredParticles)
const {
595 unsigned int numBins = globalAccumulatedHistogram.size() / 3;
596 double percentile = 0.0;
598 for (
unsigned int i = 1; i < numBins; ++i) {
599 unsigned int idx = dimension * numBins + i;
600 if (globalAccumulatedHistogram[idx] > numRequiredParticles) {
603 unsigned int numMissingParticles =
604 numRequiredParticles - globalAccumulatedHistogram[idx - 1];
605 unsigned int shift = 2;
606 while (numMissingParticles == 0) {
607 beginBin =
begin + localAccumulatedHistogram[idx - shift];
608 numMissingParticles =
609 numRequiredParticles - globalAccumulatedHistogram[idx - shift];
613 std::vector<unsigned int> numParticlesInBin(ippl::Comm->size() + 1);
614 numParticlesInBin[ippl::Comm->rank() + 1] = endBin - beginBin;
616 ippl::Comm->allreduce(
617 &(numParticlesInBin[1]), ippl::Comm->size(), std::plus<unsigned int>());
620 numParticlesInBin.begin(), numParticlesInBin.end(), numParticlesInBin.begin());
622 std::vector<double> positions(numParticlesInBin.back());
624 beginBin, endBin, positions.begin() + numParticlesInBin[ippl::Comm->rank()],
626 return std::abs(particle[0] - meanR_m[dimension]);
628 ippl::Comm->allreduce(&(positions[0]), positions.size(), std::plus<double>());
629 std::sort(positions.begin(), positions.end());
631 percentile = (*(positions.begin() + numMissingParticles - 1)
632 + *(positions.begin() + numMissingParticles))
634 for (
iterator_t it = beginBin; it != endBin; ++it) {
635 if (std::abs((*it)[0] -
meanR_m[dimension]) > percentile) {
636 return std::make_pair(percentile, it);
639 endPercentile = endBin;
643 return std::make_pair(percentile, endPercentile);
649 double localStatistics[] = {0.0, 0.0, 0.0, 0.0};
653 localStatistics[1] += rp(0);
654 localStatistics[2] += rp(1);
655 localStatistics[3] += rp(0) * rp(1);
657 ippl::Comm->allreduce(&(localStatistics[0]), 4, std::plus<double>());
659 double numParticles = localStatistics[0];
660 double perParticle = 1 / localStatistics[0];
661 double meanR = localStatistics[1] * perParticle;
662 double meanP = localStatistics[2] * perParticle;
663 double RP = localStatistics[3] * perParticle;
665 localStatistics[0] = 0.0;
666 localStatistics[1] = 0.0;
669 localStatistics[0] += std::pow(rp(0) - meanR, 2);
670 localStatistics[1] += std::pow(rp(1) - meanP, 2);
672 ippl::Comm->allreduce(&(localStatistics[0]), 2, std::plus<double>());
674 double stdR = std::sqrt(localStatistics[0] / numParticles);
675 double stdP = std::sqrt(localStatistics[1] / numParticles);
676 double sumRP = RP - meanR * meanP;
677 double squaredEps = std::pow(stdR * stdP, 2) - std::pow(sumRP, 2);
678 double normalizedEps = std::sqrt(std::max(squaredEps, 0.0));
680 return normalizedEps;
749 Np = (Np == 0) ? 1 : Np;
752 double loc_avgVel[3] = {};
753 double avgVel[3] = {};
757 Kokkos::parallel_reduce(
758 "calc moments of particle distr.", Nlocal,
760 const int k,
double& mom0,
double& mom1,
double& mom2){
763 for(
unsigned j=0; j<3; j++){
764 gamma0 += Pview(k)[j]*Pview(k)[j];
766 gamma0 = Kokkos::sqrt(gamma0+1.0);
768 mom0 += Pview(k)[0] * c / gamma0;
769 mom1 += Pview(k)[1] * c / gamma0;
770 mom2 += Pview(k)[2] * c / gamma0;
772 Kokkos::Sum<double>(loc_avgVel[0]),
773 Kokkos::Sum<double>(loc_avgVel[1]),
774 Kokkos::Sum<double>(loc_avgVel[2]));
776 ippl::Comm->barrier();
779 loc_avgVel, avgVel,
Dim, MPI_DOUBLE, MPI_SUM, ippl::Comm->getCommunicator());
781 for (
unsigned i = 0; i < 3; i++) {
782 avgVel[i] = avgVel[i] / Np;
786 double loc_tempAvg = 0.0;
798 Kokkos::parallel_reduce(
799 "calc moments of particle distr.", Nlocal,
801 const int k,
double& mom0){
804 for(
unsigned j=0; j<3; j++){
805 gamma0 += Pview(k)[j]*Pview(k)[j];
807 gamma0 = Kokkos::sqrt(gamma0+1.0);
809 mom0 += Kokkos::pow( Pview(k)[0] * c / gamma0 - avgVel[0], 2);
810 mom0 += Kokkos::pow( Pview(k)[1] * c / gamma0 - avgVel[1], 2);
811 mom0 += Kokkos::pow( Pview(k)[2] * c / gamma0 - avgVel[2], 2);
813 Kokkos::Sum<double>(loc_tempAvg));
815 ippl::Comm->barrier();
818 &loc_tempAvg, &tempAvg, 1, MPI_DOUBLE, MPI_SUM, ippl::Comm->getCommunicator());
ippl::Vector< T, Dim > Vector_t
PartBunch< T, Dim >::ConstIterator end(PartBunch< T, Dim > const &bunch)
PartBunch< T, Dim >::ConstIterator begin(PartBunch< T, Dim > const &bunch)
typename ippl::detail::ViewType< ippl::Vector< double, Dim >, 1 >::view_type view_type
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.
double haloShift
The constant parameter C to shift halo, by < w^4 > / < w^2 > ^2 - C (w=x,y,z).
double meanKineticEnergy_m
void fillMembers(std::vector< double > &)
Vector_t< double, 3 > sixtyEightPercentile_m
std::vector< Vector_t< double, 2 > >::const_iterator iterator_t
Vector_t< double, 3 > ninetyFivePercentile_m
void computePlasmaParameter(double)
Vector_t< double, 3 > minR_m
static const double percentileFourSigmasNormalDist_m
unsigned int totalNumParticles_m
Vector_t< double, 3 > ninetyNinePercentile_m
void compute(const std::vector< OpalParticle >::const_iterator &, const std::vector< OpalParticle >::const_iterator &)
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)
Vector_t< double, 3 > ninetyNine_NinetyNinePercentile_m
Vector_t< double, 3 > normalizedEps_m
Vector_t< double, 3 > normalizedEps68Percentile_m
void computeMinMaxPosition(ippl::ParticleAttrib< Vector_t< double, 3 > >::view_type &Rview, size_t Nlcoal)
Vector_t< double, 3 > meanP_m
void computeDebyeLength(ippl::ParticleAttrib< Vector_t< double, 3 > >::view_type &Rview, ippl::ParticleAttrib< Vector_t< double, 3 > >::view_type &Pview, size_t Np, size_t Nlocal, double density)
matrix_t notCentMoments_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 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 computePercentiles(const InputIt &, const InputIt &)
static const double percentileTwoSigmasNormalDist_m
Vector_t< double, 3 > normalizedEps99_99Percentile_m
void computeMeanKineticEnergy()
bool isParticleExcluded(const OpalParticle &) const
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