2#include <Kokkos_Core.hpp>
5using Matrix_t = ippl::Vector<ippl::Vector<double, 6>, 6>;
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])));
112 *
gmsg <<
"* Seed = " << randInit <<
" on all ranks" << endl;
114 randInit =
static_cast<size_t>(
Options::seed + 100 * ippl::Comm->rank());
126 for (
unsigned int i = 0; i < 6; i++) {
127 for (
unsigned int j = 0; j < 6; j++) {
132 for (
unsigned int i = 0; i < 6; i++) {
133 for (
unsigned int j = 0; j <= i; j++) {
135 for (
unsigned int k = 0; k < j; k++) {
136 sum +=
L_m[i][k] *
L_m[j][k];
139 L_m[j][j] = Kokkos::sqrt(
cov_m[j][j] - sum);
156 for (
int i = 0; i < 3; i++) {
170 double sumMin, sumMax;
171 for(
int i=0; i<6; i++){
174 for(
int j=0; j<i; j++){
182 for(
int i=0; i<3; i++){
211 const double par[6] = {0.0, 1.0, 0.0, 1.0, 0.0, 1.0};
212 using Dist_t = ippl::random::NormalDistribution<double, 3>;
213 using sampling_t = ippl::random::InverseTransformSampling<double, 3, Kokkos::DefaultExecutionSpace, Dist_t>;
216 MPI_Comm comm = MPI_COMM_WORLD;
218 MPI_Comm_size(comm, &nranks);
219 MPI_Comm_rank(comm, &rank);
222 size_t nlocal = floor(numberOfParticles / nranks);
223 size_t remaining = numberOfParticles - nlocal * nranks;
224 if (remaining > 0 && rank == 0) {
229 pc_m->create(nlocal);
230 sampling.generate(Rview, rand_pool64);
233 sampling.generate(Pview, rand_pool64);
236 for (
unsigned int i = 0; i < 6; i++) {
237 for (
unsigned int j = 0; j < 6; j++) {
243 Kokkos::parallel_for(nlocal, KOKKOS_LAMBDA(
const int k) {
244 double vec_old[6], vec[6] = {0.0};
245 for (
unsigned i = 0; i < 3; ++i) {
246 vec_old[2 * i] = Rview(k)[i];
247 vec_old[2 * i + 1] = Pview(k)[i];
249 for (
unsigned i = 0; i < 6; ++i) {
250 for (
unsigned j = 0; j < i + 1; ++j) {
251 vec[i] += L[i][j] * vec_old[j];
254 for (
unsigned i = 0; i < 3; ++i) {
255 Rview(k)[i] = vec[2 * i];
256 Pview(k)[i] = vec[2 * i + 1];
263 double meanR[3], loc_meanR[3];
266 for(
int i=0; i<3; i++){
271 Kokkos::parallel_reduce(
"calc moments of particle distr.", nlocal,
272 KOKKOS_LAMBDA(
const int k,
double& cent0,
double& cent1,
double& cent2) {
273 cent0 += Rview(k)[0];
274 cent1 += Rview(k)[1];
275 cent2 += Rview(k)[2];
277 Kokkos::Sum<double>(loc_meanR[0]), Kokkos::Sum<double>(loc_meanR[1]), Kokkos::Sum<double>(loc_meanR[2]));
280 MPI_Allreduce(loc_meanR, meanR, 3, MPI_DOUBLE, MPI_SUM, ippl::Comm->getCommunicator());
281 ippl::Comm->barrier();
283 for(
int i=0; i<3; i++){
284 meanR[i] = meanR[i]/(1.*numberOfParticles);
287 Kokkos::parallel_for(nlocal, KOKKOS_LAMBDA(
const int k) {
288 Rview(k)[0] -= meanR[0];
289 Rview(k)[1] -= meanR[1];
290 Rview(k)[2] -= meanR[2];
296 double meanP[3], loc_meanP[3];
299 for(
int i=0; i<3; i++){
303 Kokkos::parallel_reduce(
"calc moments of particle distr.", nlocal,
304 KOKKOS_LAMBDA(
const int k,
double& cent0,
double& cent1,
double& cent2) {
305 cent0 += Pview(k)[0];
306 cent1 += Pview(k)[1];
307 cent2 += Pview(k)[2];
309 Kokkos::Sum<double>(loc_meanP[0]), Kokkos::Sum<double>(loc_meanP[1]), Kokkos::Sum<double>(loc_meanP[2]));
312 MPI_Allreduce(loc_meanP, meanP, 3, MPI_DOUBLE, MPI_SUM, ippl::Comm->getCommunicator());
313 ippl::Comm->barrier();
315 for(
int i=0; i<3; i++){
316 meanP[i] = meanP[i]/(1.*numberOfParticles);
319 Kokkos::parallel_for(nlocal, KOKKOS_LAMBDA(
const int k) {
320 Pview(k)[0] -= meanP[0];
321 Pview(k)[1] -= meanP[1];
322 Pview(k)[2] -= meanP[2];
328 for(
int i=0; i<3; i++){
333 Kokkos::parallel_for(nlocal, KOKKOS_LAMBDA(
const int k) {
334 for(
int i=0; i<3; i++){
335 Rview(k)[i] += meanR[i];
336 Pview(k)[i] += meanP[i];
ippl::Vector< T, Dim > Vector_t
typename Kokkos::Random_XorShift64_Pool<> GeneratorPool
typename ippl::detail::ViewType< ippl::Vector< double, Dim >, 1 >::view_type view_type
ippl::Vector< ippl::Vector< double, 6 >, 6 > Matrix_t
ippl::Vector< ippl::Vector< double, 6 >, 6 > Matrix_t
ippl::random::NormalDistribution< double, 3 > Dist_t
int seed
The current random seed.
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)
SamplingBase(std::shared_ptr< ParticleContainer_t > &pc, std::shared_ptr< FieldContainer_t > &fc, std::shared_ptr< Distribution_t > &dist)
std::shared_ptr< Distribution_t > opalDist_m
std::shared_ptr< ParticleContainer_t > pc_m