14 std::shared_ptr<FieldContainer_t> &fc,
15 std::shared_ptr<Distribution_t> &opalDist)
16 :
SamplingBase(pc, fc, opalDist), rand_pool_m(determineRandInit()) {
21 std::shared_ptr<ParticleContainer_t> &pc,
22 std::shared_ptr<FieldContainer_t> &fc,
27 double tPulseLengthFWHM,
30 :
SamplingBase(pc, fc), rand_pool_m(determineRandInit()) {
42 std::shared_ptr<ParticleContainer_t> &pc,
47 double tPulseLengthFWHM,
70 *
gmsg <<
"* Seed = " << randInit <<
" on all ranks" <<
endl;
83 opalDist->getTPulseLengthFWHM(),
90 fc_m->setDecomp({
false,
false,
true});
97 double tPulseLengthFWHM,
140 "unitDisk", Kokkos::RangePolicy<>(nlocal, nlocal+nNew), KOKKOS_LAMBDA(
const size_t j) {
141 auto generator = rand_pool.get_state();
142 double r = Kokkos::sqrt( generator.drand(0., 1.) );
143 double theta = 2.0 *
pi * generator.drand(0., 1.);
144 rand_pool.free_state(generator);
146 Rview(j)[0] = r * Kokkos::cos(theta) * sigmaR[0];
147 Rview(j)[1] = r * Kokkos::sin(theta) * sigmaR[1];
171 Kokkos::View<bool*> tmp_invalid(
"tmp_invalid", 0);
173 pc_m->destroy(tmp_invalid,
pc_m->getLocalNum());
197 MPI_Comm comm = MPI_COMM_WORLD;
200 MPI_Comm_size(comm, &nranks);
201 MPI_Comm_rank(comm, &rank);
203 size_type nlocal = floor(nglobal/nranks);
205 size_t remaining = nglobal - nlocal*nranks;
207 if(remaining>0 && rank==0){
215 return 0.5 * (y1+y2) * fabs(x2-x1);
219 auto *mesh = &
fc_m->getMesh();
220 auto *FL = &
fc_m->getFL();
225 o[0] = -sigmaR[0] - tol;
226 e[0] = sigmaR[0] + tol;
227 o[1] = -sigmaR[1] - tol;
228 e[1] = sigmaR[1] + tol;
233 hr_m = (1.0+BoxIncr/100.)*(l /
nr_m);
234 mesh->setMeshSpacing(
hr_m);
235 mesh->setOrigin(o-0.5*
hr_m*BoxIncr/100.);
236 pc_m->getLayout().updateLayout(*FL, *mesh);
256 prmin[0] = -sigmaR[0];
257 prmax[0] = sigmaR[0];
258 prmin[1] = -sigmaR[1];
259 prmax[1] = sigmaR[1];
263 double dx = prmax[0] - prmin[0];
264 double dy = prmax[1] - prmin[1];
265 double dz = prmax[2] - prmin[2];
267 if (dx <= 0 || dy <= 0 || dz <= 0) {
268 throw std::runtime_error(
"Invalid global particle volume: prmax must be greater than prmin.");
271 double globalpvolume = dx * dy * dz;
274 auto regions =
pc_m->getLayout().getRegionLayout().gethLocalRegions();
277 if (rank < 0 ||
static_cast<size_t>(rank) >= regions.size()) {
278 throw std::runtime_error(
"Invalid rank index in gethLocalRegions()");
282 for (
unsigned d = 0; d <
Dim; ++d) {
283 locrmax[d] = regions(rank)[d].max();
284 locrmin[d] = regions(rank)[d].min();
287 if (prmax[0] >= locrmin[0] && prmin[0] <= locrmax[0] &&
288 prmax[1] >= locrmin[1] && prmin[1] <= locrmax[1] &&
289 prmax[2] >= locrmin[2] && prmin[2] <= locrmax[2]) {
291 double x1 =
std::max(prmin[0], locrmin[0]);
292 double x2 =
std::min(prmax[0], locrmax[0]);
293 double y1 =
std::max(prmin[1], locrmin[1]);
294 double y2 =
std::min(prmax[1], locrmax[1]);
295 double z1 =
std::max(prmin[2], locrmin[2]);
296 double z2 =
std::min(prmax[2], locrmax[2]);
298 if (x2 >= x1 && y2 >= y1 && z2 >= z1) {
299 double locpvolume = (x2 - x1) * (y2 - y1) * (z2 - z1);
300 if (globalpvolume > 0) {
301 nlocalNew =
static_cast<int>(totalNew * locpvolume / globalpvolume);
322 pc_m->create(nlocal);
338 *
gmsg <<
"* generate particles on a disc" <<
endl;
341 *
gmsg <<
"* new particles emmitted" <<
endl;
350 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
351 MPI_Comm_size(MPI_COMM_WORLD, &numRanks);
353 std::string filename =
"timeNpart_" + std::to_string(rank) +
".txt";
354 std::ofstream file(filename);
357 if (!file.is_open()) {
358 throw std::runtime_error(
"Failed to open file: " + filename);
374 auto rViewDevice =
pc_m->R.getView();
375 auto rView = Kokkos::create_mirror_view(rViewDevice);
376 Kokkos::deep_copy(rView,rViewDevice);
378 for(
size_type j=nlocal; j<nlocal+nNew; j++){
379 file << t <<
" " << (
emissionTime_m-t)*
c <<
" " << rView(j)[0] <<
" " << rView(j)[1] <<
"\n";
typename Kokkos::Random_XorShift64_Pool<> GeneratorPool
typename ippl::detail::ViewType< ippl::Vector< double, Dim >, 1 >::view_type view_type
Defines the FlatTop class used for sampling emitting particles.
Inform & endl(Inform &inf)
constexpr double two_pi
The value of.
constexpr double e
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.
KOKKOS_INLINE_FUNCTION Vector< T, Dim > max(const Vector< T, Dim > &a, const Vector< T, Dim > &b)
KOKKOS_INLINE_FUNCTION Vector< T, Dim > min(const Vector< T, Dim > &a, const Vector< T, Dim > &b)
void parallel_for(const std::string &name, const ExecPolicy &policy, const FunctorType &functor)
std::unique_ptr< mpi::Communicator > Comm
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.
Vector_t< double, 3 > sigmaR_m
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.
void setInternalVariables(bool emitting, double sigmaTFall, double sigmaTRise, Vector_t< double, 3 > cutoff, double tPulseLengthFWHM, Vector_t< double, 3 > sigmaR)
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.
std::shared_ptr< FieldContainer_t > fc_m
std::shared_ptr< Distribution_t > opalDist_m
std::shared_ptr< ParticleContainer_t > pc_m