28#include <gsl/gsl_histogram.h>
30#include <boost/numeric/conversion/cast.hpp>
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);
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) {
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]));
110 loc_centroid, centroid, 2 *
Dim, 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++) {
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) {
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) {
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]));
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());
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) {
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]));
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());
337 for (
unsigned int i=0; i<
Dim; i++) {
344 const std::vector<OpalParticle>::const_iterator& ,
345 const std::vector<OpalParticle>::const_iterator& ) {
350template <
class InputIt>
356 std::vector<gsl_histogram*> histograms(3);
363 for (
unsigned int d = 0; d < 3; ++d) {
365 histograms[d] = gsl_histogram_alloc(numBins);
366 gsl_histogram_set_ranges_uniform(histograms[d], 0.0, maxR(d));
368 for (InputIt it =
first; it != last; ++it) {
370 for (
unsigned int d = 0; d < 3; ++d) {
371 gsl_histogram_increment(histograms[d], std::abs(particle[2 * d] -
meanR_m[d]));
375 std::vector<int> localHistogramValues(3 * (numBins + 1)),
376 globalHistogramValues(3 * (numBins + 1));
377 for (
unsigned int d = 0; d < 3; ++d) {
379 size_t accumulated = 0;
381 localHistogramValues.begin() + d * (numBins + 1) + 1,
382 localHistogramValues.begin() + (d + 1) * (numBins + 1),
383 [&histograms, &d, &j, &accumulated]() {
384 accumulated += gsl_histogram_get(histograms[d], j++);
388 gsl_histogram_free(histograms[d]);
392 localHistogramValues.data(), globalHistogramValues.data(), 3 * (numBins + 1),
395 int numParticles68 = boost::numeric_cast<int>(
397 int numParticles95 = boost::numeric_cast<int>(
399 int numParticles99 = boost::numeric_cast<int>(
401 int numParticles99_99 = boost::numeric_cast<int>(
404 for (
int d = 0; d < 3; ++d) {
405 unsigned int localNum = last -
first, current = 0;
406 std::vector<Vector_t<double, 2>> oneDPhaseSpace(localNum);
407 for (InputIt it =
first; it != last; ++it, ++current) {
409 oneDPhaseSpace[current](0) = particle[2 * d];
410 oneDPhaseSpace[current](1) = particle[2 * d + 1];
413 oneDPhaseSpace.begin(), oneDPhaseSpace.end(),
415 return std::abs(left[0] - meanR_m[d]) < std::abs(right[0] - meanR_m[d]);
418 iterator_t endSixtyEight, endNinetyFive, endNinetyNine, endNinetyNine_NinetyNine;
419 endSixtyEight = endNinetyFive = endNinetyNine = endNinetyNine_NinetyNine =
420 oneDPhaseSpace.end();
423 oneDPhaseSpace.begin(), oneDPhaseSpace.end(), globalHistogramValues,
424 localHistogramValues, d, numParticles68);
427 oneDPhaseSpace.begin(), oneDPhaseSpace.end(), globalHistogramValues,
428 localHistogramValues, d, numParticles95);
431 oneDPhaseSpace.begin(), oneDPhaseSpace.end(), globalHistogramValues,
432 localHistogramValues, d, numParticles99);
436 oneDPhaseSpace.begin(), oneDPhaseSpace.end(), globalHistogramValues,
437 localHistogramValues, d, numParticles99_99);
482 const std::vector<int>& globalAccumulatedHistogram,
483 const std::vector<int>& localAccumulatedHistogram,
unsigned int dimension,
484 int numRequiredParticles)
const {
485 unsigned int numBins = globalAccumulatedHistogram.size() / 3;
486 double percentile = 0.0;
488 for (
unsigned int i = 1; i < numBins; ++i) {
489 unsigned int idx = dimension * numBins + i;
490 if (globalAccumulatedHistogram[idx] > numRequiredParticles) {
493 unsigned int numMissingParticles =
494 numRequiredParticles - globalAccumulatedHistogram[idx - 1];
495 unsigned int shift = 2;
496 while (numMissingParticles == 0) {
497 beginBin =
begin + localAccumulatedHistogram[idx - shift];
498 numMissingParticles =
499 numRequiredParticles - globalAccumulatedHistogram[idx - shift];
503 std::vector<unsigned int> numParticlesInBin(
ippl::Comm->size() + 1);
504 numParticlesInBin[
ippl::Comm->rank() + 1] = endBin - beginBin;
507 &(numParticlesInBin[1]),
ippl::Comm->size(), std::plus<unsigned int>());
510 numParticlesInBin.begin(), numParticlesInBin.end(), numParticlesInBin.begin());
512 std::vector<double> positions(numParticlesInBin.back());
514 beginBin, endBin, positions.begin() + numParticlesInBin[
ippl::Comm->rank()],
516 return std::abs(particle[0] - meanR_m[dimension]);
518 ippl::Comm->allreduce(&(positions[0]), positions.size(), std::plus<double>());
519 std::sort(positions.begin(), positions.end());
521 percentile = (*(positions.begin() + numMissingParticles - 1)
522 + *(positions.begin() + numMissingParticles))
524 for (
iterator_t it = beginBin; it != endBin; ++it) {
525 if (std::abs((*it)[0] -
meanR_m[dimension]) > percentile) {
526 return std::make_pair(percentile, it);
529 endPercentile = endBin;
533 return std::make_pair(percentile, endPercentile);
539 double localStatistics[] = {0.0, 0.0, 0.0, 0.0};
543 localStatistics[1] += rp(0);
544 localStatistics[2] += rp(1);
545 localStatistics[3] += rp(0) * rp(1);
547 ippl::Comm->allreduce(&(localStatistics[0]), 4, std::plus<double>());
549 double numParticles = localStatistics[0];
550 double perParticle = 1 / localStatistics[0];
551 double meanR = localStatistics[1] * perParticle;
552 double meanP = localStatistics[2] * perParticle;
553 double RP = localStatistics[3] * perParticle;
555 localStatistics[0] = 0.0;
556 localStatistics[1] = 0.0;
559 localStatistics[0] += std::pow(rp(0) - meanR, 2);
560 localStatistics[1] += std::pow(rp(1) - meanP, 2);
562 ippl::Comm->allreduce(&(localStatistics[0]), 2, std::plus<double>());
564 double stdR = std::sqrt(localStatistics[0] / numParticles);
565 double stdP = std::sqrt(localStatistics[1] / numParticles);
566 double sumRP = RP - meanR * meanP;
567 double squaredEps = std::pow(stdR * stdP, 2) - std::pow(sumRP, 2);
568 double normalizedEps = std::sqrt(
std::max(squaredEps, 0.0));
570 return normalizedEps;
639 Np = (Np == 0) ? 1 : Np;
642 double loc_avgVel[3] = {};
643 double avgVel[3] = {};
648 "calc moments of particle distr.", Nlocal,
650 const int k,
double& mom0,
double& mom1,
double& mom2){
653 for(
unsigned j=0; j<3; j++){
654 gamma0 += Pview(k)[j]*Pview(k)[j];
656 gamma0 = Kokkos::sqrt(gamma0+1.0);
658 mom0 += Pview(k)[0] *
c / gamma0;
659 mom1 += Pview(k)[1] *
c / gamma0;
660 mom2 += Pview(k)[2] *
c / gamma0;
662 Kokkos::Sum<double>(loc_avgVel[0]),
663 Kokkos::Sum<double>(loc_avgVel[1]),
664 Kokkos::Sum<double>(loc_avgVel[2]));
669 loc_avgVel, avgVel,
Dim, MPI_DOUBLE, MPI_SUM,
ippl::Comm->getCommunicator());
671 for (
unsigned i = 0; i < 3; i++) {
672 avgVel[i] = avgVel[i] / Np;
676 double loc_tempAvg = 0.0;
689 "calc moments of particle distr.", Nlocal,
691 const int k,
double& mom0){
694 for(
unsigned j=0; j<3; j++){
695 gamma0 += Pview(k)[j]*Pview(k)[j];
697 gamma0 = Kokkos::sqrt(gamma0+1.0);
699 mom0 += Kokkos::pow( Pview(k)[0] *
c / gamma0 - avgVel[0], 2);
700 mom0 += Kokkos::pow( Pview(k)[1] *
c / gamma0 - avgVel[1], 2);
701 mom0 += Kokkos::pow( Pview(k)[2] *
c / gamma0 - avgVel[2], 2);
703 Kokkos::Sum<double>(loc_tempAvg));
708 &loc_tempAvg, &tempAvg, 1, MPI_DOUBLE, MPI_SUM,
ippl::Comm->getCommunicator());
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 KOKKOS_INLINE_FUNCTION auto first()
Inform & endl(Inform &inf)
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)
KOKKOS_INLINE_FUNCTION Vector< T, Dim > max(const Vector< T, Dim > &a, const Vector< T, Dim > &b)
RangePolicy< View::rank, typenameView::execution_space, PolicyArgs... >::policy_type getRangePolicy(const View &view, int shift=0)
void parallel_reduce(const std::string &name, const ExecPolicy &policy, const FunctorType &functor, ReducerArgument &&... reducer)
std::unique_ptr< mpi::Communicator > Comm
double meanKineticEnergy_m
void fillMembers(std::vector< double > &)
Vector_t< double, 3 > sixtyEightPercentile_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
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
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
Computes the percentile and the range of all local particles that are contained therein.
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
typename detail::ViewType< T, 1, Properties... >::view_type view_type