10using GeneratorPool =
typename Kokkos::Random_XorShift64_Pool<>;
11using Dist_t = ippl::random::NormalDistribution<double, 3>;
14 std::shared_ptr<FieldContainer_t> &fc,
15 std::shared_ptr<Distribution_t> &opalDist)
29 *
gmsg <<
"* Seed = " << randInit <<
" on all ranks" << endl;
31 randInit =
static_cast<size_t>(
Options::seed + 100 * ippl::Comm->rank());
62 fc_m->setDecomp({
false,
false,
true});
79 "unitDisk", Kokkos::RangePolicy<>(nlocal, nlocal+nNew), KOKKOS_LAMBDA(
const size_t j) {
80 auto generator = rand_pool.get_state();
81 double r = Kokkos::sqrt( generator.drand(0., 1.) );
82 double theta = 2.0 *
pi * generator.drand(0., 1.);
83 rand_pool.free_state(generator);
85 Rview(j)[0] = r * Kokkos::cos(theta) * sigmaR[0];
86 Rview(j)[1] = r * Kokkos::sin(theta) * sigmaR[1];
110 Kokkos::View<bool*> tmp_invalid(
"tmp_invalid", 0);
112 pc_m->destroy(tmp_invalid,
pc_m->getLocalNum());
136 MPI_Comm comm = MPI_COMM_WORLD;
139 MPI_Comm_size(comm, &nranks);
140 MPI_Comm_rank(comm, &rank);
142 size_type nlocal = floor(nglobal/nranks);
144 size_t remaining = nglobal - nlocal*nranks;
146 if(remaining>0 && rank==0){
154 return 0.5 * (y1+y2) * fabs(x2-x1);
158 auto *mesh = &
fc_m->getMesh();
159 auto *FL = &
fc_m->getFL();
161 ippl::Vector<double, 3> o;
162 ippl::Vector<double, 3> e;
164 o[0] = -sigmaR[0] - tol;
165 e[0] = sigmaR[0] + tol;
166 o[1] = -sigmaR[1] - tol;
167 e[1] = sigmaR[1] + tol;
171 ippl::Vector<double, 3> l = e - o;
172 hr_m = (1.0+BoxIncr/100.)*(l /
nr_m);
173 mesh->setMeshSpacing(
hr_m);
174 mesh->setOrigin(o-0.5*
hr_m*BoxIncr/100.);
175 pc_m->getLayout().updateLayout(*FL, *mesh);
195 prmin[0] = -sigmaR[0];
196 prmax[0] = sigmaR[0];
197 prmin[1] = -sigmaR[1];
198 prmax[1] = sigmaR[1];
202 double dx = prmax[0] - prmin[0];
203 double dy = prmax[1] - prmin[1];
204 double dz = prmax[2] - prmin[2];
206 if (dx <= 0 || dy <= 0 || dz <= 0) {
207 throw std::runtime_error(
"Invalid global particle volume: prmax must be greater than prmin.");
210 double globalpvolume = dx * dy * dz;
213 auto regions =
pc_m->getLayout().getRegionLayout().gethLocalRegions();
214 int rank = ippl::Comm->rank();
216 if (rank < 0 ||
static_cast<size_t>(rank) >= regions.size()) {
217 throw std::runtime_error(
"Invalid rank index in gethLocalRegions()");
221 for (
unsigned d = 0; d <
Dim; ++d) {
222 locrmax[d] = regions(rank)[d].max();
223 locrmin[d] = regions(rank)[d].min();
226 if (prmax[0] >= locrmin[0] && prmin[0] <= locrmax[0] &&
227 prmax[1] >= locrmin[1] && prmin[1] <= locrmax[1] &&
228 prmax[2] >= locrmin[2] && prmin[2] <= locrmax[2]) {
230 double x1 = std::max(prmin[0], locrmin[0]);
231 double x2 = std::min(prmax[0], locrmax[0]);
232 double y1 = std::max(prmin[1], locrmin[1]);
233 double y2 = std::min(prmax[1], locrmax[1]);
234 double z1 = std::max(prmin[2], locrmin[2]);
235 double z2 = std::min(prmax[2], locrmax[2]);
237 if (x2 >= x1 && y2 >= y1 && z2 >= z1) {
238 double locpvolume = (x2 - x1) * (y2 - y1) * (z2 - z1);
239 if (globalpvolume > 0) {
240 nlocalNew =
static_cast<int>(totalNew * locpvolume / globalpvolume);
261 pc_m->create(nlocal);
277 *
gmsg <<
"* generate particles on a disc" << endl;
280 *
gmsg <<
"* new particles emmitted" << endl;
289 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
290 MPI_Comm_size(MPI_COMM_WORLD, &numRanks);
292 std::string filename =
"timeNpart_" + std::to_string(rank) +
".txt";
293 std::ofstream file(filename);
296 if (!file.is_open()) {
297 throw std::runtime_error(
"Failed to open file: " + filename);
313 auto rViewDevice =
pc_m->R.getView();
314 auto rView = Kokkos::create_mirror_view(rViewDevice);
315 Kokkos::deep_copy(rView,rViewDevice);
317 for(
size_type j=nlocal; j<nlocal+nNew; j++){
318 file << t <<
" " << (
emissionTime_m-t)*c <<
" " << rView(j)[0] <<
" " << rView(j)[1] <<
"\n";
325 ippl::Comm->barrier();
ParticleContainer< double, 3 > ParticleContainer_t
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
Distribution Distribution_t
ippl::random::NormalDistribution< double, 3 > Dist_t
FieldContainer< double, 3 > FieldContainer_t
Defines the FlatTop class used for sampling emitting particles.
constexpr double two_pi
The value of.
constexpr double c
The velocity of light in m/s.
constexpr double pi
The value of.
int seed
The current random seed.
void setNr(Vector_t< double, 3 > nr)
Sets the number of grid points per direction.
void testEmitParticles(size_type nsteps, double dt) override
Tests particle emission over a given number of steps.
double distArea_m
Total area of the flattop distribution.
double FlatTopProfile(double t)
Computes the flat-top profile value at a given time.
bool emitting_m
Flag for particle emission status.
Vector_t< double, 3 > nr_m
Number of grid points per direction.
static size_t determineRandInit()
Determines the random seed initialization.
void allocateParticles(size_t numberOfParticles)
Allocates memory for a given number of particles.
double emissionTime_m
Total emission time.
double sigmaTRise_m
Standard deviation for rise time profile.
size_type totalN_m
Total number of particles.
GeneratorPool rand_pool_m
Random number generator pool.
double sigmaTFall_m
Standard deviation for fall time profile.
bool withDomainDecomp_m
Flag for domain decomposition.
void initDomainDecomp(double BoxIncr) override
Initializes the domain decomposition.
Vector_t< double, 3 > hr_m
Grid spacing.
double integrateTrapezoidal(double x1, double x2, double y1, double y2)
Integrates using the trapezoidal rule.
double fallTime_m
Time duration for the fall phase.
size_t computeNlocalUniformly(size_t nglobal)
Computes the local number of particles uniformly distributed among ranks.
double normalizedFlankArea_m
Normalized area of the distribution flanks.
void setWithDomainDecomp(bool withDomainDecomp) override
Sets whether to use domain decomposition.
void emitParticles(double t, double dt) override
Emits new particles within a given time interval.
double riseTime_m
Time duration for the rise phase.
void generateParticles(size_t &numberOfParticles, Vector_t< double, 3 > nr) override
Generates particles with a given number and grid configuration.
double countEnteringParticlesPerRank(double t0, double tf)
Counts the number of particles entering per rank in a given time interval.
void generateUniformDisk(size_type nlocal, size_t nNew)
Generates particles (x,y) uniformly on a disk distribution.
void testNumEmitParticles(size_type nsteps, double dt) override
Tests the number of emitted particles over a given number of steps.
Vector_t< double, 3 > cutoffR_m
Cutoff radius.
double flattopTime_m
Time duration of when the time profile is flat.
FlatTop(std::shared_ptr< ParticleContainer_t > &pc, std::shared_ptr< FieldContainer_t > &fc, std::shared_ptr< Distribution_t > &opalDist)
Constructor for FlatTop.
ippl::detail::size_type size_type
void setParameters(const std::shared_ptr< Distribution_t > &opalDist)
Sets distribution parameters.
SamplingBase(std::shared_ptr< ParticleContainer_t > &pc, std::shared_ptr< FieldContainer_t > &fc, std::shared_ptr< Distribution_t > &dist)
std::shared_ptr< FieldContainer_t > fc_m
std::shared_ptr< Distribution_t > opalDist_m
std::shared_ptr< ParticleContainer_t > pc_m