WarpX
BinaryCollision.H
Go to the documentation of this file.
1 /* Copyright 2020-2021 Yinjian Zhao, David Grote, Neil Zaim
2  *
3  * This file is part of WarpX.
4  *
5  * License: BSD-3-Clause-LBNL
6  */
7 #ifndef WARPX_PARTICLES_COLLISION_BINARYCOLLISION_H_
8 #define WARPX_PARTICLES_COLLISION_BINARYCOLLISION_H_
9 
19 #include "Utils/ParticleUtils.H"
21 #include "WarpX.H"
22 
25 
26 #include <AMReX.H>
27 #include <AMReX_Algorithm.H>
28 #include <AMReX_BLassert.H>
29 #include <AMReX_Config.H>
30 #include <AMReX_DenseBins.H>
31 #include <AMReX_Extension.H>
32 #include <AMReX_Geometry.H>
33 #include <AMReX_GpuAtomic.H>
34 #include <AMReX_GpuControl.H>
35 #include <AMReX_GpuDevice.H>
36 #include <AMReX_GpuLaunch.H>
37 #include <AMReX_GpuQualifiers.H>
38 #include <AMReX_LayoutData.H>
39 #include <AMReX_MFIter.H>
40 #include <AMReX_PODVector.H>
41 #include <AMReX_ParmParse.H>
42 #include <AMReX_Particles.H>
43 #include <AMReX_ParticleTile.H>
44 #include <AMReX_Random.H>
45 #include <AMReX_REAL.H>
46 #include <AMReX_Scan.H>
47 #include <AMReX_Utility.H>
48 #include <AMReX_Vector.H>
49 
50 #include <AMReX_BaseFwd.H>
51 
52 #include <cmath>
53 #include <string>
54 
64 template <typename CollisionFunctorType,
65  typename CopyTransformFunctorType = NoParticleCreationFunc>
66 class BinaryCollision final
67  : public CollisionBase
68 {
69  // Define shortcuts for frequently-used type names
72  using ParticleBins = amrex::DenseBins<ParticleType>;
73  using SoaData_type = WarpXParticleContainer::ParticleTileType::ParticleTileDataType;
75 
76 public:
83  BinaryCollision (std::string collision_name)
84  : CollisionBase(collision_name)
85  {
86  if(m_species_names.size() != 2)
87  amrex::Abort("Binary collision " + collision_name + " must have exactly two species.");
88 
89  if (m_species_names[0] == m_species_names[1])
90  m_isSameSpecies = true;
91  else
92  m_isSameSpecies = false;
93 
94  m_binary_collision_functor = CollisionFunctorType(collision_name);
95 
96  amrex::ParmParse pp_collision_name(collision_name);
97  pp_collision_name.queryarr("product_species", m_product_species);
99  m_copy_transform_functor = CopyTransformFunctorType();
100  }
101 
102  virtual ~BinaryCollision () = default;
103 
111  void doCollisions (amrex::Real cur_time, MultiParticleContainer* mypc) override
112  {
113  const amrex::Real dt = WarpX::GetInstance().getdt(0);
114  if ( int(std::floor(cur_time/dt)) % m_ndt != 0 ) return;
115 
117  auto& species2 = mypc->GetParticleContainerFromName(m_species_names[1]);
118 
119  // In case of particle creation, create the necessary vectors
120  const int n_product_species = m_product_species.size();
121  amrex::Vector<WarpXParticleContainer*> product_species_vector;
122  amrex::Vector<SmartCopy> copy_species1;
123  amrex::Vector<SmartCopy> copy_species2;
124  for (int i = 0; i < n_product_species; i++)
125  {
126  auto& product = mypc->GetParticleContainerFromName(m_product_species[i]);
127  product.defineAllParticleTiles();
128  product_species_vector.push_back(&product);
129  SmartCopyFactory copy_factory_species1(species1, product);
130  SmartCopyFactory copy_factory_species2(species2, product);
131  copy_species1.push_back(copy_factory_species1.getSmartCopy());
132  copy_species2.push_back(copy_factory_species2.getSmartCopy());
133  }
134 #ifdef AMREX_USE_GPU
135  amrex::Gpu::DeviceVector<SmartCopy> device_copy_species1(n_product_species);
136  amrex::Gpu::DeviceVector<SmartCopy> device_copy_species2(n_product_species);
137  amrex::Gpu::copyAsync(amrex::Gpu::hostToDevice, copy_species1.begin(),
138  copy_species1.end(), device_copy_species1.begin());
139  amrex::Gpu::copyAsync(amrex::Gpu::hostToDevice, copy_species2.begin(),
140  copy_species2.end(), device_copy_species2.begin());
141  amrex::Gpu::streamSynchronize();
142  auto copy_species1_data = device_copy_species1.data();
143  auto copy_species2_data = device_copy_species2.data();
144 #else
145  auto copy_species1_data = copy_species1.data();
146  auto copy_species2_data = copy_species2.data();
147 #endif
149  species1.defineAllParticleTiles();
150  species2.defineAllParticleTiles();
151  }
152 
153  // Enable tiling
154  amrex::MFItInfo info;
155  if (amrex::Gpu::notInLaunchRegion()) info.EnableTiling(species1.tile_size);
156 
157  // Loop over refinement levels
158  for (int lev = 0; lev <= species1.finestLevel(); ++lev){
159 
160  amrex::LayoutData<amrex::Real>* cost = WarpX::getCosts(lev);
161 
162  // Loop over all grids/tiles at this level
163 #ifdef AMREX_USE_OMP
164  info.SetDynamic(true);
165 #pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
166 #endif
167  for (amrex::MFIter mfi = species1.MakeMFIter(lev, info); mfi.isValid(); ++mfi){
169  {
170  amrex::Gpu::synchronize();
171  }
172  amrex::Real wt = amrex::second();
173 
174  doCollisionsWithinTile( lev, mfi, species1, species2, product_species_vector,
175  copy_species1_data, copy_species2_data);
176 
178  {
179  amrex::Gpu::synchronize();
180  wt = amrex::second() - wt;
181  amrex::HostDevice::Atomic::Add( &(*cost)[mfi.index()], wt);
182  }
183  }
184  }
185  }
186 
198  int const lev, amrex::MFIter const& mfi,
199  WarpXParticleContainer& species_1,
200  WarpXParticleContainer& species_2,
201  amrex::Vector<WarpXParticleContainer*> product_species_vector,
202  SmartCopy* copy_species1, SmartCopy* copy_species2)
203  {
204  using namespace ParticleUtils;
205  using namespace amrex::literals;
206 
207  int const ndt = m_ndt;
208  CollisionFunctorType binary_collision_functor = m_binary_collision_functor;
209  const bool have_product_species = m_have_product_species;
210 
211  // Store product species data in vectors
212  const int n_product_species = m_product_species.size();
213  amrex::Vector<SoaData_type> soa_products;
214  amrex::Vector<GetParticlePosition> get_position_products;
215  amrex::Vector<index_type> products_np;
216  constexpr int getpos_offset = 0;
217  for (int i = 0; i < n_product_species; i++)
218  {
219  ParticleTileType& ptile_product = product_species_vector[i]->ParticlesAt(lev, mfi);
220  soa_products.push_back(ptile_product.getParticleTileData());
221  get_position_products.push_back(GetParticlePosition(ptile_product,
222  getpos_offset));
223  products_np.push_back(ptile_product.numParticles());
224  }
225 #ifdef AMREX_USE_GPU
226  amrex::Gpu::DeviceVector<SoaData_type> device_soa_products(n_product_species);
227  amrex::Gpu::DeviceVector<GetParticlePosition> device_get_position_products(n_product_species);
228  amrex::Gpu::DeviceVector<index_type> device_products_np(n_product_species);
229  amrex::Gpu::copyAsync(amrex::Gpu::hostToDevice, soa_products.begin(),
230  soa_products.end(),
231  device_soa_products.begin());
232  amrex::Gpu::copyAsync(amrex::Gpu::hostToDevice, get_position_products.begin(),
233  get_position_products.end(),
234  device_get_position_products.begin());
235  amrex::Gpu::copyAsync(amrex::Gpu::hostToDevice, products_np.begin(),
236  products_np.end(),
237  device_products_np.begin());
238  amrex::Gpu::streamSynchronize();
239  auto soa_products_data = device_soa_products.data();
240  auto get_position_products_data = device_get_position_products.data();
241  auto products_np_data = device_products_np.data();
242 #else
243  auto soa_products_data = soa_products.data();
244  auto get_position_products_data = get_position_products.data();
245  auto products_np_data = products_np.data();
246 #endif
247 
248  if ( m_isSameSpecies ) // species_1 == species_2
249  {
250  // Extract particles in the tile that `mfi` points to
251  ParticleTileType& ptile_1 = species_1.ParticlesAt(lev, mfi);
252 
253  // Find the particles that are in each cell of this tile
254  ParticleBins bins_1 = findParticlesInEachCell( lev, mfi, ptile_1 );
255 
256  // Loop over cells, and collide the particles in each cell
257 
258  // Extract low-level data
259  int const n_cells = bins_1.numBins();
260  // - Species 1
261  const auto soa_1 = ptile_1.getParticleTileData();
262  index_type* indices_1 = bins_1.permutationPtr();
263  index_type const* cell_offsets_1 = bins_1.offsetsPtr();
264  amrex::Real q1 = species_1.getCharge();
265  amrex::Real m1 = species_1.getMass();
266  auto get_position_1 = GetParticlePosition(ptile_1, getpos_offset);
267 
268  const amrex::Real dt = WarpX::GetInstance().getdt(lev);
269  amrex::Geometry const& geom = WarpX::GetInstance().Geom(lev);
270 #if defined WARPX_DIM_XZ
271  auto dV = geom.CellSize(0) * geom.CellSize(1);
272 #elif defined WARPX_DIM_RZ
273  amrex::Box const& cbx = mfi.tilebox(amrex::IntVect::TheZeroVector()); //Cell-centered box
274  const auto lo = lbound(cbx);
275  const auto hi = ubound(cbx);
276  int const nz = hi.y-lo.y+1;
277  auto dr = geom.CellSize(0);
278  auto dz = geom.CellSize(1);
279 #elif (AMREX_SPACEDIM == 3)
280  auto dV = geom.CellSize(0) * geom.CellSize(1) * geom.CellSize(2);
281 #endif
282 
283 
284  /*
285  The following calculations are only required when creating product particles
286  */
287  const int n_cells_products = have_product_species ? n_cells: 0;
288  amrex::Gpu::DeviceVector<index_type> n_pairs_in_each_cell(n_cells_products);
289  auto p_n_pairs_in_each_cell = n_pairs_in_each_cell.dataPtr();
290 
291  // Compute how many pairs in each cell and store in n_pairs_in_each_cell array
292  // For a single species, the number of pair in a cell is half the number of particles
293  // in that cell, rounded up to the next higher integer.
294  amrex::ParallelFor( n_cells_products,
295  [=] AMREX_GPU_DEVICE (int i_cell) noexcept
296  {
297  const auto n_part_in_cell = cell_offsets_1[i_cell+1] - cell_offsets_1[i_cell];
298  // Particular case: if there's only 1 particle in a cell, then there's no pair
299  p_n_pairs_in_each_cell[i_cell] = (n_part_in_cell == 1)? 0: (n_part_in_cell+1)/2;
300  }
301  );
302 
303  // Start indices of the pairs in a cell. Will be used for particle creation.
304  amrex::Gpu::DeviceVector<index_type> pair_offsets(n_cells_products);
305  const auto n_total_pairs = amrex::Scan::ExclusiveSum(n_cells_products,
306  p_n_pairs_in_each_cell, pair_offsets.data());
307  auto p_pair_offsets = pair_offsets.dataPtr();
308 
309  // mask: equal to 1 if particle creation occurs for a given pair, 0 otherwise
310  amrex::Gpu::DeviceVector<index_type> mask(n_total_pairs);
311  auto p_mask = mask.dataPtr();
312  // Will be filled with the index of the first particle of a given pair
313  amrex::Gpu::DeviceVector<index_type> pair_indices_1(n_total_pairs);
314  auto p_pair_indices_1 = pair_indices_1.dataPtr();
315  // Will be filled with the index of the second particle of a given pair
316  amrex::Gpu::DeviceVector<index_type> pair_indices_2(n_total_pairs);
317  auto p_pair_indices_2 = pair_indices_2.dataPtr();
318  // How much weight should be given to the produced particles (and removed from the
319  // reacting particles)
320  amrex::Gpu::DeviceVector<amrex::ParticleReal> pair_reaction_weight(n_total_pairs);
321  auto p_pair_reaction_weight = pair_reaction_weight.dataPtr();
322  /*
323  End of calculations only required when creating product particles
324  */
325 
326 
327  // Loop over cells
328  amrex::ParallelForRNG( n_cells,
329  [=] AMREX_GPU_DEVICE (int i_cell, amrex::RandomEngine const& engine) noexcept
330  {
331  // The particles from species1 that are in the cell `i_cell` are
332  // given by the `indices_1[cell_start_1:cell_stop_1]`
333  index_type const cell_start_1 = cell_offsets_1[i_cell];
334  index_type const cell_stop_1 = cell_offsets_1[i_cell+1];
335  index_type const cell_half_1 = (cell_start_1+cell_stop_1)/2;
336 
337  // Same but for the pairs
338  index_type const cell_start_pair = have_product_species?
339  p_pair_offsets[i_cell] : 0;
340 
341  // Do not collide if there is only one particle in the cell
342  if ( cell_stop_1 - cell_start_1 <= 1 ) return;
343 
344  // shuffle
346  indices_1, cell_start_1, cell_half_1, engine );
347 #if defined WARPX_DIM_RZ
348  int ri = (i_cell - i_cell%nz) / nz;
349  auto dV = MathConst::pi*(2.0_rt*ri+1.0_rt)*dr*dr*dz;
350 #endif
351  // Call the function in order to perform collisions
352  // If there are product species, mask, p_pair_indices_1/2, and
353  // p_pair_reaction_weight are filled here
354  binary_collision_functor(
355  cell_start_1, cell_half_1,
356  cell_half_1, cell_stop_1,
357  indices_1, indices_1,
358  soa_1, soa_1, get_position_1, get_position_1,
359  q1, q1, m1, m1, dt*ndt, dV,
360  cell_start_pair, p_mask, p_pair_indices_1, p_pair_indices_2,
361  p_pair_reaction_weight, engine );
362  }
363  );
364 
365  // Create the new product particles and define their initial values
366  // num_added: how many particles of each product species have been created
367  const amrex::Vector<int> num_added = m_copy_transform_functor(soa_1, soa_1,
368  soa_products_data,
369  get_position_1, get_position_1,
370  get_position_products_data,
371  p_mask, products_np_data,
372  copy_species1, copy_species2,
373  p_pair_indices_1, p_pair_indices_2,
374  p_pair_reaction_weight);
375 
376  for (int i = 0; i < n_product_species; i++)
377  {
378  ParticleTileType& ptile_product = product_species_vector[i]->ParticlesAt(lev, mfi);
379  setNewParticleIDs(ptile_product, products_np[i], num_added[i]);
380  }
381  }
382  else // species_1 != species_2
383  {
384  // Extract particles in the tile that `mfi` points to
385  ParticleTileType& ptile_1 = species_1.ParticlesAt(lev, mfi);
386  ParticleTileType& ptile_2 = species_2.ParticlesAt(lev, mfi);
387 
388  // Find the particles that are in each cell of this tile
389  ParticleBins bins_1 = findParticlesInEachCell( lev, mfi, ptile_1 );
390  ParticleBins bins_2 = findParticlesInEachCell( lev, mfi, ptile_2 );
391 
392  // Loop over cells, and collide the particles in each cell
393 
394  // Extract low-level data
395  int const n_cells = bins_1.numBins();
396  // - Species 1
397  const auto soa_1 = ptile_1.getParticleTileData();
398  index_type* indices_1 = bins_1.permutationPtr();
399  index_type const* cell_offsets_1 = bins_1.offsetsPtr();
400  amrex::Real q1 = species_1.getCharge();
401  amrex::Real m1 = species_1.getMass();
402  auto get_position_1 = GetParticlePosition(ptile_1, getpos_offset);
403  // - Species 2
404  const auto soa_2 = ptile_2.getParticleTileData();
405  index_type* indices_2 = bins_2.permutationPtr();
406  index_type const* cell_offsets_2 = bins_2.offsetsPtr();
407  amrex::Real q2 = species_2.getCharge();
408  amrex::Real m2 = species_2.getMass();
409  auto get_position_2 = GetParticlePosition(ptile_2, getpos_offset);
410 
411  const amrex::Real dt = WarpX::GetInstance().getdt(lev);
412  amrex::Geometry const& geom = WarpX::GetInstance().Geom(lev);
413 #if defined WARPX_DIM_XZ
414  auto dV = geom.CellSize(0) * geom.CellSize(1);
415 #elif defined WARPX_DIM_RZ
416  amrex::Box const& cbx = mfi.tilebox(amrex::IntVect::TheZeroVector()); //Cell-centered box
417  const auto lo = lbound(cbx);
418  const auto hi = ubound(cbx);
419  int nz = hi.y-lo.y+1;
420  auto dr = geom.CellSize(0);
421  auto dz = geom.CellSize(1);
422 #elif (AMREX_SPACEDIM == 3)
423  auto dV = geom.CellSize(0) * geom.CellSize(1) * geom.CellSize(2);
424 #endif
425 
426 
427  /*
428  The following calculations are only required when creating product particles
429  */
430  const int n_cells_products = have_product_species ? n_cells: 0;
431  amrex::Gpu::DeviceVector<index_type> n_pairs_in_each_cell(n_cells_products);
432  auto p_n_pairs_in_each_cell = n_pairs_in_each_cell.dataPtr();
433 
434  // Compute how many pairs in each cell and store in n_pairs_in_each_cell array
435  // For different species, the number of pairs in a cell is the number of particles of
436  // the species that has the most particles in that cell
437  amrex::ParallelFor( n_cells_products,
438  [=] AMREX_GPU_DEVICE (int i_cell) noexcept
439  {
440  const auto n_part_in_cell_1 = cell_offsets_1[i_cell+1] - cell_offsets_1[i_cell];
441  const auto n_part_in_cell_2 = cell_offsets_2[i_cell+1] - cell_offsets_2[i_cell];
442  // Particular case: no pair if a species has no particle in that cell
443  if (n_part_in_cell_1 == 0 || n_part_in_cell_2 == 0)
444  p_n_pairs_in_each_cell[i_cell] = 0;
445  else
446  p_n_pairs_in_each_cell[i_cell] =
447  amrex::max(n_part_in_cell_1,n_part_in_cell_2);
448  }
449  );
450 
451  // Start indices of the pairs in a cell. Will be used for particle creation
452  amrex::Gpu::DeviceVector<index_type> pair_offsets(n_cells_products);
453  auto n_total_pairs = amrex::Scan::ExclusiveSum(n_cells_products,
454  p_n_pairs_in_each_cell, pair_offsets.data());
455  auto p_pair_offsets = pair_offsets.dataPtr();
456 
457  // mask: equal to 1 if particle creation occurs for a given pair, 0 otherwise
458  amrex::Gpu::DeviceVector<index_type> mask(n_total_pairs);
459  auto p_mask = mask.dataPtr();
460  // Will be filled with the index of the first particle of a given pair
461  amrex::Gpu::DeviceVector<index_type> pair_indices_1(n_total_pairs);
462  auto p_pair_indices_1 = pair_indices_1.dataPtr();
463  // Will be filled with the index of the second particle of a given pair
464  amrex::Gpu::DeviceVector<index_type> pair_indices_2(n_total_pairs);
465  auto p_pair_indices_2 = pair_indices_2.dataPtr();
466  // How much weight should be given to the produced particles (and removed from the
467  // reacting particles)
468  amrex::Gpu::DeviceVector<amrex::ParticleReal> pair_reaction_weight(n_total_pairs);
469  auto p_pair_reaction_weight = pair_reaction_weight.dataPtr();
470  /*
471  End of calculations only required when creating product particles
472  */
473 
474 
475  // Loop over cells
476  amrex::ParallelForRNG( n_cells,
477  [=] AMREX_GPU_DEVICE (int i_cell, amrex::RandomEngine const& engine) noexcept
478  {
479  // The particles from species1 that are in the cell `i_cell` are
480  // given by the `indices_1[cell_start_1:cell_stop_1]`
481  index_type const cell_start_1 = cell_offsets_1[i_cell];
482  index_type const cell_stop_1 = cell_offsets_1[i_cell+1];
483  // Same for species 2
484  index_type const cell_start_2 = cell_offsets_2[i_cell];
485  index_type const cell_stop_2 = cell_offsets_2[i_cell+1];
486  // Same but for the pairs
487  index_type const cell_start_pair = have_product_species?
488  p_pair_offsets[i_cell] : 0;
489 
490  // ux from species1 can be accessed like this:
491  // ux_1[ indices_1[i] ], where i is between
492  // cell_start_1 (inclusive) and cell_start_2 (exclusive)
493 
494  // Do not collide if one species is missing in the cell
495  if ( cell_stop_1 - cell_start_1 < 1 ||
496  cell_stop_2 - cell_start_2 < 1 ) return;
497 
498  // shuffle
499  ShuffleFisherYates(indices_1, cell_start_1, cell_stop_1, engine);
500  ShuffleFisherYates(indices_2, cell_start_2, cell_stop_2, engine);
501 #if defined WARPX_DIM_RZ
502  int ri = (i_cell - i_cell%nz) / nz;
503  auto dV = MathConst::pi*(2.0_rt*ri+1.0_rt)*dr*dr*dz;
504 #endif
505  // Call the function in order to perform collisions
506  // If there are product species, p_mask, p_pair_indices_1/2, and
507  // p_pair_reaction_weight are filled here
508  binary_collision_functor(
509  cell_start_1, cell_stop_1, cell_start_2, cell_stop_2,
510  indices_1, indices_2,
511  soa_1, soa_2, get_position_1, get_position_2,
512  q1, q2, m1, m2, dt*ndt, dV,
513  cell_start_pair, p_mask, p_pair_indices_1, p_pair_indices_2,
514  p_pair_reaction_weight, engine );
515  }
516  );
517 
518 
519  // Create the new product particles and define their initial values
520  // num_added: how many particles of each product species have been created
521  const amrex::Vector<int> num_added = m_copy_transform_functor(soa_1, soa_2,
522  soa_products_data,
523  get_position_1, get_position_2,
524  get_position_products_data,
525  p_mask, products_np_data,
526  copy_species1, copy_species2,
527  p_pair_indices_1, p_pair_indices_2,
528  p_pair_reaction_weight);
529 
530  for (int i = 0; i < n_product_species; i++)
531  {
532  ParticleTileType& ptile_product = product_species_vector[i]->ParticlesAt(lev, mfi);
533  setNewParticleIDs(ptile_product, products_np[i], num_added[i]);
534  }
535 
536  } // end if ( m_isSameSpecies)
537 
538  }
539 
540 private:
541 
544  amrex::Vector<std::string> m_product_species;
545  // functor that performs collisions within a cell
546  CollisionFunctorType m_binary_collision_functor;
547  // functor that creates new particles and initializes their parameters
548  CopyTransformFunctorType m_copy_transform_functor;
549 
550 };
551 
552 #endif // WARPX_PARTICLES_COLLISION_BINARYCOLLISION_H_
This class does nothing and is used as second template parameter for binary collisions that do not cr...
Definition: BinaryCollisionUtils.H:22
amrex::Vector< amrex::Real > getdt() const
Definition: WarpX.H:536
string species1
Definition: video_yt.py:32
bool m_have_product_species
Definition: BinaryCollision.H:543
static long load_balance_costs_update_algo
Definition: WarpX.H:145
AMREX_GPU_HOST_DEVICE AMREX_INLINE void ShuffleFisherYates(T_index *array, T_index const is, T_index const ie, amrex::RandomEngine const &engine)
Definition: ShuffleFisherYates.H:20
void doCollisionsWithinTile(int const lev, amrex::MFIter const &mfi, WarpXParticleContainer &species_1, WarpXParticleContainer &species_2, amrex::Vector< WarpXParticleContainer *> product_species_vector, SmartCopy *copy_species1, SmartCopy *copy_species2)
Definition: BinaryCollision.H:197
WarpXParticleContainer & GetParticleContainerFromName(std::string name) const
Definition: MultiParticleContainer.H:80
WarpXParticleContainer::ParticleType ParticleType
Definition: BinaryCollision.H:70
This class performs generic binary collisions.
Definition: BinaryCollision.H:66
void defineAllParticleTiles() noexcept
Definition: WarpXParticleContainer.cpp:1075
CopyTransformFunctorType m_copy_transform_functor
Definition: BinaryCollision.H:548
Definition: MultiParticleContainer.H:64
CollisionFunctorType m_binary_collision_functor
Definition: BinaryCollision.H:546
load balance according to in-code timer-based weights (i.e., with costs)
Definition: WarpXAlgorithmSelection.H:90
WarpXParticleContainer::ParticleTileType ParticleTileType
Definition: ParticleUtils.cpp:30
virtual ~BinaryCollision()=default
void doCollisions(amrex::Real cur_time, MultiParticleContainer *mypc) override
Definition: BinaryCollision.H:111
WarpXParticleContainer::ParticleTileType::ParticleTileDataType SoaData_type
Definition: BinaryCollision.H:73
int m_ndt
Definition: CollisionBase.H:33
amrex::ParticleReal getCharge() const
Definition: WarpXParticleContainer.H:317
ParticleBins findParticlesInEachCell(int const lev, MFIter const &mfi, ParticleTileType const &ptile)
Definition: ParticleUtils.cpp:37
amrex::ParticleReal getMass() const
Definition: WarpXParticleContainer.H:319
void setNewParticleIDs(PTile &ptile, int old_size, int num_added)
Sets the ids of newly created particles to the next values.
Definition: SmartUtils.H:51
amrex::DenseBins< ParticleType > ParticleBins
Definition: BinaryCollision.H:72
ParticleBins::index_type index_type
Definition: ParticleUtils.cpp:32
static amrex::LayoutData< amrex::Real > * getCosts(int lev)
Definition: WarpX.cpp:2140
amrex::Vector< std::string > m_species_names
Definition: CollisionBase.H:32
i
Definition: check_interp_points_and_weights.py:171
int dz
Definition: compute_domain.py:36
WarpXParticleContainer::ParticleTileType ParticleTileType
Definition: BinaryCollision.H:71
WarpXParticleContainer::ParticleType ParticleType
Definition: ParticleUtils.cpp:29
Definition: ParticleUtils.cpp:25
static WarpX & GetInstance()
Definition: WarpX.cpp:200
ParticleBins::index_type index_type
Definition: BinaryCollision.H:74
BinaryCollision(std::string collision_name)
Constructor of the BinaryCollision class.
Definition: BinaryCollision.H:83
amrex::Vector< std::string > m_product_species
Definition: BinaryCollision.H:544
Definition: CollisionBase.H:17
This is a functor for performing a "smart copy" that works in both host and device code...
Definition: SmartCopy.H:33
static std::array< amrex::Real, 3 > CellSize(int lev)
Definition: WarpX.cpp:1957
bool m_isSameSpecies
Definition: BinaryCollision.H:542
Functor that can be used to extract the positions of the macroparticles inside a ParallelFor kernel...
Definition: GetAndSetPosition.H:48
SmartCopy getSmartCopy() const noexcept
Definition: SmartCopy.H:153
A factory for creating SmartCopy functors.
Definition: SmartCopy.H:131
Definition: WarpXParticleContainer.H:110