8using Dist_t = ippl::random::NormalDistribution<double, 3>;
11 std::shared_ptr<ParticleContainer_t> pc, std::shared_ptr<FieldContainer_t> fc,
13 :
SamplingBase(pc, fc, opalDist), rand_pool_m(determineRandInit()) {
18 std::shared_ptr<ParticleContainer_t> pc, std::shared_ptr<FieldContainer_t> fc,
21 :
SamplingBase(pc, fc), rand_pool_m(determineRandInit()) {
26 std::shared_ptr<ParticleContainer_t> pc,
bool emitting,
double sigmaTFall,
40 *
gmsg <<
"* Seed = " << randInit <<
" on all ranks" << endl;
42 randInit =
static_cast<size_t>(
Options::seed + 100 * ippl::Comm->rank());
55 fc_m->setDecomp({
false,
false,
true});
96 auto dtView =
pc_m->dt.getView();
103 auto range = Kokkos::RangePolicy<>(nlocal, nlocal + nNew);
106 Kokkos::parallel_for(
107 "unitDisk_R", range, KOKKOS_LAMBDA(
const size_t j) {
108 auto generator = rand_pool.get_state();
109 double r = Kokkos::sqrt(generator.drand(0., 1.));
110 double theta = 2.0 * pi * generator.drand(0., 1.);
111 double frac = generator.drand(0., 1.);
112 rand_pool.free_state(generator);
114 Rview(j)[0] = r * Kokkos::cos(theta) * sigmaR[0] + R0[0];
115 Rview(j)[1] = r * Kokkos::sin(theta) * sigmaR[1] + R0[1];
116 Rview(j)[2] = 0.0 + R0[2];
125 dtView(j) = frac * dt;
134 Kokkos::parallel_for(
135 "unitDisk_P_astra", range, KOKKOS_LAMBDA(
const size_t j) {
136 auto generator = rand_pool.get_state();
137 double rand1 = generator.drand(0., 1.);
138 double rand2 = generator.drand(0., 1.);
139 rand_pool.free_state(generator);
141 double phi = 2.0 * Kokkos::acos(Kokkos::sqrt(rand1));
142 double theta = 2.0 * pi * rand2;
144 Pview(j)[0] = pTot * Kokkos::sin(phi) * Kokkos::cos(theta);
145 Pview(j)[1] = pTot * Kokkos::sin(phi) * Kokkos::sin(theta);
146 Pview(j)[2] = pTot * Kokkos::fabs(Kokkos::cos(phi));
150 Kokkos::parallel_for(
151 "unitDisk_P_none", range, KOKKOS_LAMBDA(
const size_t j) { Pview(j) = P0; });
169 Kokkos::parallel_for(
170 "unitDisk_Zcorr", range, KOKKOS_LAMBDA(
const size_t j) {
171 double px = Pview(j)[0];
172 double py = Pview(j)[1];
173 double pz = Pview(j)[2];
174 double gamma = Kokkos::sqrt(1.0 + px * px + py * py + pz * pz);
175 double beta_z = pz / gamma;
176 Rview(j)[2] += 0.5 * beta_z * c * dtView(j);
224 const int nranks = ippl::Comm->size();
225 const int rank = ippl::Comm->rank();
227 const size_t nranks_u =
static_cast<size_t>(nranks > 0 ? nranks : 1);
228 const size_type nlocal = nglobal / nranks_u;
229 const size_t remaining = nglobal - nlocal * nranks_u;
232 if (remaining > 0 &&
static_cast<size_t>(rank) < remaining) {
239 return 0.5 * (y1 + y2) * fabs(x2 - x1);
243 auto* mesh = &
fc_m->getMesh();
244 auto* FL = &
fc_m->getFL();
246 ippl::Vector<double, 3> o;
247 ippl::Vector<double, 3> e;
249 o[0] = -sigmaR[0] - tol;
250 e[0] = sigmaR[0] + tol;
251 o[1] = -sigmaR[1] - tol;
252 e[1] = sigmaR[1] + tol;
256 ippl::Vector<double, 3> l = e - o;
257 hr_m = (1.0 + BoxIncr / 100.) * (l /
nr_m);
258 mesh->setMeshSpacing(
hr_m);
259 mesh->setOrigin(o - 0.5 *
hr_m * BoxIncr / 100.);
260 pc_m->getLayout().updateLayout(*FL, *mesh);
267 const double totalNewD = std::floor(
static_cast<double>(
totalN_m) * tArea /
distArea_m);
361 Inform msgAll = Inform(
"FlatTop::emitParticles", INFORM_ALL_NODES);
364 double tShift = t -
t0_m;
368 msgAll << level5 <<
"* " << nNew <<
" new particles to be emitted" << endl;
373 msgAll << level5 <<
"* " << nlocal <<
" particles already in the container" << endl;
380 pc_m->createParticles(nNew);
384 msgAll << level3 <<
"* generate particles on a disc" << endl;
389 pc_m->markMomentsDirty();
391 msgAll << level3 <<
"* " << nNew <<
" new particles emmitted" << endl;
400 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
401 MPI_Comm_size(MPI_COMM_WORLD, &numRanks);
403 std::string filename =
"timeNpart_" + std::to_string(rank) +
".txt";
404 std::ofstream file(filename);
407 if (!file.is_open()) {
408 throw std::runtime_error(
"Failed to open file: " + filename);
418 pc_m->createParticles(nNew);
424 auto rViewDevice =
pc_m->R.getView();
425 auto rView = Kokkos::create_mirror_view(rViewDevice);
426 Kokkos::deep_copy(rView, rViewDevice);
428 for (
size_type j = nlocal; j < nlocal + nNew; j++) {
429 file << t <<
" " << (
emissionTime_m - t) * c <<
" " << rView(j)[0] <<
" " << rView(j)[1]
437 ippl::Comm->barrier();
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::random::NormalDistribution< double, 3 > Dist_t
Defines the FlatTop class used for sampling emitting particles.
typename Kokkos::Random_XorShift64_Pool<> GeneratorPool
KOKKOS_INLINE_FUNCTION double euclidean_norm(const Vector_t< T, D > &v)
double getSigmaTFall() const
double getTPulseLengthFWHM() const
void setTEmission(double tEmission)
ippl::Vector< double, 3 > getSigmaR() const
double getSigmaTRise() const
ippl::Vector< double, 3 > getCutoffR() const
void setNr(Vector_t< double, 3 > nr)
Sets the number of grid points per direction.
void generateUniformDisk(size_type nlocal, size_t nNew, double dt)
Generates particles (x,y) uniformly on a disk distribution.
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.
FlatTop(std::shared_ptr< ParticleContainer_t > pc, std::shared_ptr< FieldContainer_t > fc, Distribution_t *opalDist)
Constructor for FlatTop.
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.
void setParameters(Distribution_t *opalDist)
Sets distribution parameters.
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.
size_type countEnteringParticlesPerRank(double t0, double tf)
Counts the number of particles entering per rank in a given time interval.
ippl::detail::size_type size_type
Vector_t< double, 3 > P0_m
Vector_t< double, 3 > R0_m
Emission source offset: position R0, momentum P0, start time t0 (applied in sample step).
std::shared_ptr< FieldContainer_t > fc_m
size_t computeLocalEmitCount(size_t totalToSample) const
Computes the number of particles this rank should emit so that the global total equals totalToSample ...
std::string emissionModel_m
Distribution_t * opalDist_m
void fillPolarization(size_t startIdx, size_t count)
std::shared_ptr< ParticleContainer_t > pc_m
int seed
The current random seed.
constexpr double two_pi
The value of.
constexpr double c
The velocity of light in m/s.
constexpr double pi
The value of.