8#ifndef PHOTON_INITIALIZERS
9#define PHOTON_INITIALIZERS
12#include <AMReX_Config.H>
13#include <AMReX_MFIter.H>
14#include <AMReX_Math.H>
15#include <AMReX_REAL.H>
16#include <AMReX_Random.H>
17#include <AMReX_RandomEngine.H>
18#include <AMReX_Scan.H>
23#include "AMReX_Array.H"
24#include "AMReX_GpuDevice.H"
25#include "AMReX_ParallelDescriptor.H"
41template <
typename StructType,
typename ParticleContainerClass>
43 const CCTK_REAL *real_params,
44 const CCTK_INT *int_params) {
46 CCTK_INFO(
"Initializing particles using the "
47 "random_spherical_photons_per_container_initializer");
49 const CCTK_INT level = 0;
50 const CCTK_REAL radius = real_params[0];
53 const auto dx = pc.Geom(level).CellSizeArray();
56 const auto p_lo = pc.Geom(level).ProbLoArray();
57 const auto p_hi = pc.Geom(level).ProbHiArray();
59 const int n_procs = amrex::ParallelDescriptor::NProcs();
60 const int proc_id = amrex::ParallelDescriptor::MyProc();
62 const int total_particles = int_params[0];
63 const int local_particles_size =
64 total_particles / n_procs + (proc_id < total_particles % n_procs);
67 for (amrex::MFIter mfi = pc.MakeMFIter(level); mfi.isValid(); ++mfi) {
74 for (amrex::MFIter mfi = pc.MakeMFIter(level); mfi.isValid(); ++mfi) {
76 const unsigned int particles_per_tile =
77 local_particles_size / total_tiles +
78 (current_tile < local_particles_size % total_tiles);
81 const amrex::Box &tile_box = mfi.tilebox();
84 const auto lo = amrex::lbound(tile_box);
85 const auto hi = amrex::ubound(tile_box);
87 auto &particles = pc.GetParticles(level);
88 auto &particle_tile = pc.DefineAndReturnParticleTile(level, mfi);
91 auto old_size = particle_tile.GetArrayOfStructs().size();
94 auto new_size = old_size + particles_per_tile;
95 particle_tile.resize(new_size);
99 auto *p_struct = particle_tile.GetArrayOfStructs()().data();
100 auto arrdata = particle_tile.GetStructOfArrays().realarray();
102 std::vector<long> particle_ids(particles_per_tile);
103 for (
int i = 0; i < particles_per_tile; ++i) {
104 particle_ids[i] = ParticleContainerClass::ParticleType::NextID();
108 amrex::Gpu::DeviceVector<long> d_particle_ids(particle_ids.size());
109 amrex::Gpu::copyAsync(amrex::Gpu::hostToDevice, particle_ids.begin(),
110 particle_ids.end(), d_particle_ids.begin());
111 const long *id_ptr = d_particle_ids.data();
113 amrex::ParallelForRNG(
115 [=] AMREX_GPU_DEVICE(
int i,
116 amrex::RandomEngine
const &engine)
noexcept {
118 int pidx = old_size + i;
121 const amrex::Real ratio[AMREX_SPACEDIM] = {
122 (std::abs(p_hi[0] - p_lo[0]) - (radius) * 2.) * 0.5 *
125 Random(engine) * M_PI, Random(engine) * 2. * M_PI};
127 auto &p = p_struct[pidx];
132 p.pos(0) = ratio[0] * std::sin(ratio[1]) * std::cos(ratio[2]);
133 p.pos(1) = ratio[0] * std::sin(ratio[1]) * std::sin(ratio[2]);
134 p.pos(2) = ratio[0] * std::cos(ratio[1]);
137 arrdata[StructType::vx][pidx] = 2. * Random(engine) - 1.0;
138 arrdata[StructType::vy][pidx] = 2. * Random(engine) - 1.0;
139 arrdata[StructType::vz][pidx] = 2. * Random(engine) - 1.0;
140 arrdata[StructType::ln_E][pidx] = 0;
142 CCTK_VWarn(1, __LINE__, __FILE__, CCTK_THORNSTRING,
143 "Number of particles created at tile %d: %d ", current_tile,
149 pc.SortParticlesByCell();
151 CCTK_VINFO(
"%d particles created", pc.TotalNumberOfParticles());
165template <
typename StructType,
typename ParticleContainerClass>
167 const CCTK_REAL *real_params,
168 const CCTK_INT *int_params) {
170 CCTK_INFO(
"Initializing particles using the "
171 "random_uniform_photons_per_container_initializer");
173 const CCTK_INT level = 0;
174 const CCTK_REAL radius = real_params[0];
177 const auto p_lo = pc.Geom(level).ProbLoArray();
178 const auto p_hi = pc.Geom(level).ProbHiArray();
180 const int n_procs = amrex::ParallelDescriptor::NProcs();
181 const int proc_id = amrex::ParallelDescriptor::MyProc();
183 const int total_particles = int_params[0];
184 const int local_particles_size =
185 total_particles / n_procs + (proc_id < total_particles % n_procs);
188 for (amrex::MFIter mfi = pc.MakeMFIter(level); mfi.isValid(); ++mfi) {
192 int current_tile = 0;
195 for (amrex::MFIter mfi = pc.MakeMFIter(level); mfi.isValid(); ++mfi) {
197 const unsigned int particles_per_tile =
198 local_particles_size / total_tiles +
199 (current_tile < local_particles_size % total_tiles);
202 const amrex::Box &tile_box = mfi.tilebox();
205 const auto lo = amrex::lbound(tile_box);
206 const auto hi = amrex::ubound(tile_box);
208 auto &particles = pc.GetParticles(level);
209 auto &particle_tile = pc.DefineAndReturnParticleTile(level, mfi);
212 auto old_size = particle_tile.GetArrayOfStructs().size();
215 auto new_size = old_size + particles_per_tile;
216 particle_tile.resize(new_size);
220 auto *p_struct = particle_tile.GetArrayOfStructs()().data();
221 auto arrdata = particle_tile.GetStructOfArrays().realarray();
223 std::vector<long> particle_ids(particles_per_tile);
224 for (
int i = 0; i < particles_per_tile; ++i) {
225 particle_ids[i] = ParticleContainerClass::ParticleType::NextID();
229 amrex::Gpu::DeviceVector<long> d_particle_ids(particle_ids.size());
230 amrex::Gpu::copyAsync(amrex::Gpu::hostToDevice, particle_ids.begin(),
231 particle_ids.end(), d_particle_ids.begin());
232 const long *id_ptr = d_particle_ids.data();
234 amrex::ParallelForRNG(
236 [=] AMREX_GPU_DEVICE(
int i,
237 amrex::RandomEngine
const &engine)
noexcept {
239 int pidx = old_size + i;
240 auto &p = p_struct[pidx];
246 p.pos(0) = Random(engine) * (p_hi[0] - p_lo[0]) + p_lo[0];
247 p.pos(1) = Random(engine) * (p_hi[1] - p_lo[1]) + p_lo[1];
248 p.pos(2) = Random(engine) * (p_hi[2] - p_lo[2]) + p_lo[2];
249 }
while ((p.pos(0) * p.pos(0) + p.pos(1) * p.pos(1) +
250 p.pos(2) * p.pos(2)) <
251 (radius) * (radius));
254 arrdata[StructType::vx][pidx] = 2. * Random(engine) - 1.0;
255 arrdata[StructType::vy][pidx] = 2. * Random(engine) - 1.0;
256 arrdata[StructType::vz][pidx] = 2. * Random(engine) - 1.0;
257 arrdata[StructType::ln_E][pidx] = 0;
259 CCTK_VWarn(1, __LINE__, __FILE__, CCTK_THORNSTRING,
260 "Number of particles created at tile %d: %d ", current_tile,
266 pc.SortParticlesByCell();
268 CCTK_VINFO(
"%d particles created", pc.TotalNumberOfParticles());
Barycentric Lagrange interpolation related functions definitions.
void random_spherical_initializer(ParticleContainerClass &pc, const CCTK_REAL *real_params, const CCTK_INT *int_params)
This function random initializes particles spherically distributed around a sphere of radius real_par...
Definition: PhotonsInitializers.hxx:42
void random_uniform_initializer(ParticleContainerClass &pc, const CCTK_REAL *real_params, const CCTK_INT *int_params)
This function random initializes particles uniformly distributed in a box avoiding a sphere of radius...
Definition: PhotonsInitializers.hxx:166
Interpolators namespace.
Definition: ParticlesContainer.hxx:39