OPALX (Object Oriented Parallel Accelerator Library for Exascale) MINIorX
OPALX
Gaussian.cpp
Go to the documentation of this file.
1#include "Distribution.h"
2#include "SamplingBase.hpp"
3#include "Gaussian.h"
4#include <memory>
5#include <cmath>
6
14Gaussian::Gaussian(std::shared_ptr<ParticleContainer_t> &pc,
15 std::shared_ptr<FieldContainer_t> &fc,
16 std::shared_ptr<Distribution_t> &opalDist)
17 : SamplingBase(pc, fc, opalDist) {
18 samperTimer_m = IpplTimings::getTimer("SamplingTimer");
20 setSigmaP(opalDist->getSigmaP());
21 setSigmaR(opalDist->getSigmaR());
22 setAvrgpz(opalDist->getAvrgpz());
23 setCutoffR(opalDist->getCutoffR());
24}
25
26Gaussian::Gaussian(std::shared_ptr<ParticleContainer_t> pc,
27 const Vector_t<double, 3>& sigmaR,
28 const Vector_t<double, 3>& sigmaP,
29 double avrgpz, const Vector_t<double, 3>& cutoffR,
30 bool fixMeanR)
31 : SamplingBase(pc) {
32 setSigmaR(sigmaR);
33 setSigmaP(sigmaP);
34 setAvrgpz(avrgpz);
35 setCutoffR(cutoffR);
36 setFixMeanR(fixMeanR);
37
38 samperTimer_m = IpplTimings::getTimer("SamplingTimer");
40}
41
43 extern Inform* gmsg;
44 size_t randInit;
45
46 if (Options::seed == -1) {
47 randInit = 1234567;
48 *gmsg << "* Seed = " << randInit << " on all ranks" << endl;
49 } else {
50 randInit = static_cast<size_t>(Options::seed + 100 * ippl::Comm->rank());
51 }
52
53 GeneratorPool rand_pool64(randInit);
54 randPool_m = rand_pool64;
55 return;
56}
57
64void Gaussian::generateParticles(size_t& numberOfParticles, Vector_t<double, 3> /*nr*/) {
65 auto rand_pool64 = randPool_m;
66
68
69 double mu[3], sd[3];
70
73
74 for (int i = 0; i < 3; i++) {
75 mu[i] = 0.0;
76 sd[i] = sigmaR_m[i];
77 rmin(i) = (rmin(i) + mu[i]) * sigmaR_m[i];
78 rmax(i) = (rmax(i) + mu[i]) * sigmaR_m[i];
79 }
80
81 view_type &Rview = pc_m->R.getView();
82 const double par[6] = {mu[0], sd[0], mu[1], sd[1], mu[2], sd[2]};
83
86 Dist_t dist(par);
87
88 MPI_Comm comm = MPI_COMM_WORLD;
89 int nranks, rank;
90 MPI_Comm_size(comm, &nranks);
91 MPI_Comm_rank(comm, &rank);
92
93 size_t nlocal = floor(numberOfParticles / nranks);
94 size_t remaining = numberOfParticles - nlocal * nranks;
95
96 if (remaining > 0 && rank == 0) {
97 nlocal += remaining;
98 }
99
100 sampling_t sampling(dist, rmax, rmin, rmax, rmin, nlocal);
101 nlocal = sampling.getLocalSamplesNum();
102 pc_m->create(nlocal);
103 sampling.generate(Rview, rand_pool64);
104
105 if (fixMeanR_m) {
106
107 double meanR[3], loc_meanR[3];
108 for(int i=0; i<3; i++){
109 meanR[i] = 0.0;
110 loc_meanR[i] = 0.0;
111 }
112
114 "calc moments of particle distr.", nlocal,
115 KOKKOS_LAMBDA(
116 const int k, double& cent0, double& cent1, double& cent2) {
117 cent0 += Rview(k)[0];
118 cent1 += Rview(k)[1];
119 cent2 += Rview(k)[2];
120 },
121 Kokkos::Sum<double>(loc_meanR[0]), Kokkos::Sum<double>(loc_meanR[1]), Kokkos::Sum<double>(loc_meanR[2]));
123
124 MPI_Allreduce(loc_meanR, meanR, 3, MPI_DOUBLE, MPI_SUM, ippl::Comm->getCommunicator());
125 ippl::Comm->barrier();
126
127 for(int i=0; i<3; i++){
128 meanR[i] = meanR[i]/(1.0*numberOfParticles);
129 }
130
132 nlocal, KOKKOS_LAMBDA(
133 const int k) {
134 Rview(k)[0] -= meanR[0];
135 Rview(k)[1] -= meanR[1];
136 Rview(k)[2] -= meanR[2];
137 }
138 );
140 }
141
142 for (int i = 0; i < 3; i++) {
143 mu[i] = 0.0;
144 sd[i] = sigmaP_m[i];
145 }
146
147 view_type &Pview = pc_m->P.getView();
149 nlocal,
150 ippl::random::randn<double, 3>(Pview, rand_pool64, mu, sd)
151 );
153
154 double avrgpz = avrgpz_m;
156 nlocal,
157 KOKKOS_LAMBDA(const int k) {
158 Pview(k)[2] += avrgpz;
159 }
160 );
162
164}
165
Inform * gmsg
Definition: changes.cpp:7
typename Kokkos::Random_XorShift64_Pool<> GeneratorPool
typename ippl::detail::ViewType< ippl::Vector< double, Dim >, 1 >::view_type view_type
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
int seed
The current random seed.
Definition: Options.cpp:37
void fence()
Definition: Ippl.cpp:103
void parallel_for(const std::string &name, const ExecPolicy &policy, const FunctorType &functor)
void parallel_reduce(const std::string &name, const ExecPolicy &policy, const FunctorType &functor, ReducerArgument &&... reducer)
std::unique_ptr< mpi::Communicator > Comm
Definition: Ippl.h:22
Vector_t< double, 3 > sigmaP_m
Definition: Gaussian.h:130
Vector_t< double, 3 > sigmaR_m
Standard deviations for position and momentum distributions.
Definition: Gaussian.h:129
void initRandomPool()
Initializes the random number generator pool.
Definition: Gaussian.cpp:42
void setCutoffR(const Vector_t< double, 3 > &cutoffR)
Definition: Gaussian.h:93
double avrgpz_m
Average momentum in the z-direction.
Definition: Gaussian.h:135
void setFixMeanR(bool fixMeanR)
Definition: Gaussian.h:107
bool fixMeanR_m
Flag to exactly fix the mean position of particles after sampling.
Definition: Gaussian.h:145
void setSigmaR(const Vector_t< double, 3 > &sigmaR)
Definition: Gaussian.h:81
void generateParticles(size_t &numberOfParticles, Vector_t< double, 3 > nr) override
Generates particles with a Gaussian distribution.
Definition: Gaussian.cpp:64
Vector_t< double, 3 > cutoffR_m
Cutoff multiplier for position distribution.
Definition: Gaussian.h:140
GeneratorPool randPool_m
Pool of random number generators for parallel sampling.
Definition: Gaussian.h:124
Gaussian(std::shared_ptr< ParticleContainer_t > &pc, std::shared_ptr< FieldContainer_t > &fc, std::shared_ptr< Distribution_t > &opalDist)
Constructor for the Gaussian sampler.
Definition: Gaussian.cpp:14
void setAvrgpz(double avrgpz)
Definition: Gaussian.h:89
void setSigmaP(const Vector_t< double, 3 > &sigmaP)
Definition: Gaussian.h:85
IpplTimings::TimerRef samperTimer_m
Timer for performance profiling.
Definition: Gaussian.h:46
std::shared_ptr< ParticleContainer_t > pc_m
A class for inverse transform sampling.
Functor to generate random numbers from a normal distribution.
Definition: Randn.h:26
Definition: Inform.h:40
static TimerRef getTimer(const char *nm)
Definition: IpplTimings.h:150
static void stopTimer(TimerRef t)
Definition: IpplTimings.h:156
static void startTimer(TimerRef t)
Definition: IpplTimings.h:153