2#include <Kokkos_Core.hpp>
14 std::shared_ptr<FieldContainer_t> &fc,
15 std::shared_ptr<Distribution_t> &opalDist)
19 for (
unsigned int i = 0; i < 6; i++) {
20 for (
unsigned int j = 0; j < 6; j++) {
49 for (
unsigned int i = 0; i < 6; i++) {
50 for (
unsigned int j = 0; j < 6; j++) {
53 cov_m[i][j] = sigmaR[i/2]*sigmaR[i/2];
56 cov_m[i][j] = sigmaP[i/2]*sigmaP[i/2];
89 Kokkos::sqrt(
cov_m[2][2]),
90 Kokkos::sqrt(
cov_m[4][4])));
93 Kokkos::sqrt(
cov_m[3][3]),
94 Kokkos::sqrt(
cov_m[5][5])));
113 *
gmsg <<
"* Seed = " << randInit <<
" on all ranks" <<
endl;
127 for (
unsigned int i = 0; i < 6; i++) {
128 for (
unsigned int j = 0; j < 6; j++) {
133 for (
unsigned int i = 0; i < 6; i++) {
134 for (
unsigned int j = 0; j <= i; j++) {
136 for (
unsigned int k = 0; k < j; k++) {
137 sum +=
L_m[i][k] *
L_m[j][k];
140 L_m[j][j] = Kokkos::sqrt(
cov_m[j][j] - sum);
157 for (
int i = 0; i < 3; i++) {
171 double sumMin, sumMax;
172 for(
int i=0; i<6; i++){
175 for(
int j=0; j<i; j++){
183 for(
int i=0; i<3; i++){
212 const double par[6] = {0.0, 1.0, 0.0, 1.0, 0.0, 1.0};
217 MPI_Comm comm = MPI_COMM_WORLD;
219 MPI_Comm_size(comm, &nranks);
220 MPI_Comm_rank(comm, &rank);
223 size_t nlocal = floor(numberOfParticles / nranks);
224 size_t remaining = numberOfParticles - nlocal * nranks;
225 if (remaining > 0 && rank == 0) {
230 pc_m->create(nlocal);
231 sampling.generate(Rview, rand_pool64);
234 sampling.generate(Pview, rand_pool64);
237 for (
unsigned int i = 0; i < 6; i++) {
238 for (
unsigned int j = 0; j < 6; j++) {
245 double vec_old[6], vec[6] = {0.0};
246 for (
unsigned i = 0; i < 3; ++i) {
247 vec_old[2 * i] = Rview(k)[i];
248 vec_old[2 * i + 1] = Pview(k)[i];
250 for (
unsigned i = 0; i < 6; ++i) {
251 for (
unsigned j = 0; j < i + 1; ++j) {
252 vec[i] += L[i][j] * vec_old[j];
255 for (
unsigned i = 0; i < 3; ++i) {
256 Rview(k)[i] = vec[2 * i];
257 Pview(k)[i] = vec[2 * i + 1];
264 double meanR[3], loc_meanR[3];
267 for(
int i=0; i<3; i++){
273 KOKKOS_LAMBDA(
const int k,
double& cent0,
double& cent1,
double& cent2) {
274 cent0 += Rview(k)[0];
275 cent1 += Rview(k)[1];
276 cent2 += Rview(k)[2];
278 Kokkos::Sum<double>(loc_meanR[0]), Kokkos::Sum<double>(loc_meanR[1]), Kokkos::Sum<double>(loc_meanR[2]));
281 MPI_Allreduce(loc_meanR, meanR, 3, MPI_DOUBLE, MPI_SUM,
ippl::Comm->getCommunicator());
284 for(
int i=0; i<3; i++){
285 meanR[i] = meanR[i]/(1.*numberOfParticles);
289 Rview(k)[0] -= meanR[0];
290 Rview(k)[1] -= meanR[1];
291 Rview(k)[2] -= meanR[2];
297 double meanP[3], loc_meanP[3];
300 for(
int i=0; i<3; i++){
305 KOKKOS_LAMBDA(
const int k,
double& cent0,
double& cent1,
double& cent2) {
306 cent0 += Pview(k)[0];
307 cent1 += Pview(k)[1];
308 cent2 += Pview(k)[2];
310 Kokkos::Sum<double>(loc_meanP[0]), Kokkos::Sum<double>(loc_meanP[1]), Kokkos::Sum<double>(loc_meanP[2]));
313 MPI_Allreduce(loc_meanP, meanP, 3, MPI_DOUBLE, MPI_SUM,
ippl::Comm->getCommunicator());
316 for(
int i=0; i<3; i++){
317 meanP[i] = meanP[i]/(1.*numberOfParticles);
321 Pview(k)[0] -= meanP[0];
322 Pview(k)[1] -= meanP[1];
323 Pview(k)[2] -= meanP[2];
329 for(
int i=0; i<3; i++){
335 for(
int i=0; i<3; i++){
336 Rview(k)[i] += meanR[i];
337 Pview(k)[i] += meanP[i];
typename Kokkos::Random_XorShift64_Pool<> GeneratorPool
typename ippl::detail::ViewType< ippl::Vector< double, Dim >, 1 >::view_type view_type
Inform & endl(Inform &inf)
int seed
The current random seed.
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
Vector_t< double, 6 > normMax_m
Vector_t< double, 3 > sigmaP_m
IpplTimings::TimerRef samplerTimer_m
Timer for performance profiling.
bool fixMeanR_m
Flag to exactly fix the mean R and P of particles after sampling.
Vector_t< double, 3 > meanP_m
void setCutoffR(const Vector_t< double, 3 > &cutoffR)
void setMeanP(const Vector_t< double, 3 > &meanP)
Vector_t< double, 6 > max_m
Vector_t< double, 3 > normPmin_m
void setCutoffP(const Vector_t< double, 3 > &cutoffP)
Vector_t< double, 3 > pmax_m
void ComputeCholeskyFactorization()
Computes the Cholesky factorization of the covariance matrix.
Vector_t< double, 3 > rmin_m
Vector_t< double, 3 > rmax_m
Vector_t< double, 3 > pmin_m
Vector_t< double, 3 > cutoffR_m
Cutoff multipliers for position and momentum distributions.
Vector_t< double, 6 > min_m
Min and Max bounds for all 6 dimensions (R0,P0,R1,P1,R2,P2).
Vector_t< double, 3 > normPmax_m
void setFixMeanR(bool fixMeanR)
void setMeanR(const Vector_t< double, 3 > &meanR)
Vector_t< double, 6 > normMin_m
void initRandomPool()
Initializes the random number generator pool.
Vector_t< double, 3 > normRmax_m
void generateParticles(size_t &numberOfParticles, Vector_t< double, 3 > nr) override
Generates particles based on the defined Gaussian distribution.
Vector_t< double, 3 > meanR_m
Vector_t< double, 3 > sigmaR_m
Standard deviations for position and momentum distributions.
MultiVariateGaussian(std::shared_ptr< ParticleContainer_t > &pc, std::shared_ptr< FieldContainer_t > &fc, std::shared_ptr< Distribution_t > &opalDist)
Constructor for MultiVariateGaussian.
void setSigmaP(const Vector_t< double, 3 > &sigmaP)
GeneratorPool randPool_m
Pool of random number generators for parallel sampling.
void setSigmaR(const Vector_t< double, 3 > &sigmaR)
void ComputeCenteredBounds()
Computes centered bounds for the particle distribution.
Vector_t< double, 3 > cutoffP_m
Vector_t< double, 3 > normRmin_m
void setFixMeanP(bool fixMeanP)
std::shared_ptr< Distribution_t > opalDist_m
std::shared_ptr< ParticleContainer_t > pc_m
A class for inverse transform sampling.
static TimerRef getTimer(const char *nm)
static void stopTimer(TimerRef t)
static void startTimer(TimerRef t)