pyAMReX
ParticleContainer.H
Go to the documentation of this file.
1 /* Copyright 2022 The AMReX Community
2  *
3  * Authors: Ryan Sandberg, Axel Huebl
4  * License: BSD-3-Clause-LBNL
5  */
6 #pragma once
7 
8 #include "pyAMReX.H"
9 
10 #include "Particle.H"
11 #include "ArrayOfStructs.H"
12 #include "StructOfArrays.H"
13 #include "ParticleTile.H"
14 
15 #include <AMReX_BoxArray.H>
16 #include <AMReX_GpuAllocators.H>
17 #include <AMReX_IntVect.H>
18 #include <AMReX_ParIter.H>
19 #include <AMReX_Particle.H>
20 #include <AMReX_Particles.H>
23 #include <AMReX_ParticleTile.H>
24 #include <AMReX_ArrayOfStructs.H>
25 
26 #include <string>
27 #include <sstream>
28 
29 
30 template <typename T_ParticleType, int T_NArrayReal=0, int T_NArrayInt=0>
31 std::string particle_type_suffix ()
32 {
33  std::string suffix;
34  if constexpr (T_ParticleType::is_soa_particle)
35  suffix = "pureSoA_" +
36  std::to_string(T_NArrayReal) + "_" +
37  std::to_string(T_NArrayInt);
38  else
39  suffix = std::to_string(T_ParticleType::NReal) + "_" +
40  std::to_string(T_ParticleType::NInt) + "_" +
41  std::to_string(T_NArrayReal) + "_" +
42  std::to_string(T_NArrayInt);
43 
44  return suffix;
45 }
46 
47 template <bool is_const, typename T_ParIterBase>
48 void make_Base_Iterators (py::module &m, std::string allocstr)
49 {
50  using namespace amrex;
51 
52  using iterator_base = T_ParIterBase;
53  using container = typename iterator_base::ContainerType;
54  using ParticleType = typename container::ParticleType;
55  constexpr int NArrayReal = container::NArrayReal;
56  constexpr int NArrayInt = container::NArrayInt;
57 
58  std::string const suffix = particle_type_suffix<ParticleType, NArrayReal, NArrayInt>();
59  std::string particle_it_base_name = std::string("Par");
60  if (is_const) particle_it_base_name += "Const";
61  particle_it_base_name += "IterBase_" + suffix + "_" + allocstr;
62  auto py_it_base = py::class_<iterator_base, MFIter>(m, particle_it_base_name.c_str(), py::dynamic_attr())
63  .def(py::init<container&, int>(),
64  // while the created iterator (argument 1: this) exists,
65  // keep the ParticleContainer (argument 2) alive
66  py::keep_alive<1, 2>(),
67  py::arg("particle_container"), py::arg("level"))
68  //.def(py::init<container&, int, MFItInfo&>(),
69  // py::keep_alive<1, 2>(),
70  // py::arg("particle_container"), py::arg("level"), py::arg("info"))
71 
72  .def("particle_tile", &iterator_base::GetParticleTile,
73  py::return_value_policy::reference_internal)
74  .def("soa", &iterator_base::GetStructOfArrays,
75  py::return_value_policy::reference_internal)
76 
77  .def_property_readonly_static("is_soa_particle", [](const py::object&){ return ParticleType::is_soa_particle;})
78  .def_property_readonly("size", &iterator_base::numParticles,
79  "the number of particles on this tile")
80  .def_property_readonly("num_particles", &iterator_base::numParticles)
81  .def_property_readonly("num_real_particles", &iterator_base::numRealParticles)
82  .def_property_readonly("num_neighbor_particles", &iterator_base::numNeighborParticles)
83  .def_property_readonly("level", &iterator_base::GetLevel)
84  .def_property_readonly("pair_index", &iterator_base::GetPairIndex)
85  .def_property_readonly("is_valid", &iterator_base::isValid)
86  .def("geom", &iterator_base::Geom, py::arg("level"))
87 
88  // helpers for iteration __next__
89  .def("_incr", &iterator_base::operator++)
90  .def("finalize", &iterator_base::Finalize)
91  ;
92 
93  // only legacy particle has an AoS data structure for positions and id+cpu
94  if constexpr (!ParticleType::is_soa_particle)
95  py_it_base.def("aos",
96  &iterator_base::GetArrayOfStructs,
97  py::return_value_policy::reference_internal);
98 }
99 
100 template <bool is_const, typename T_ParIter, template<class> class Allocator=amrex::DefaultAllocator>
101 void make_Iterators (py::module &m, std::string allocstr)
102 {
103  using namespace amrex;
104 
105  using iterator = T_ParIter;
106  using container = typename iterator::ContainerType;
107  using ParticleType = typename container::ParticleType;
108  constexpr int NArrayReal = container::NArrayReal;
109  constexpr int NArrayInt = container::NArrayInt;
110 
112  make_Base_Iterators< is_const, iterator_base >(m, allocstr);
113 
114  std::string const suffix = particle_type_suffix<ParticleType, NArrayReal, NArrayInt>();
115  auto particle_it_name = std::string("Par");
116  if (is_const) particle_it_name += "Const";
117  particle_it_name += std::string("Iter_") + suffix + "_" + allocstr;
118  py::class_<iterator, iterator_base>(m, particle_it_name.c_str())
119  .def("__repr__",
120  [particle_it_name](iterator const & pti) {
121  std::string r = "<amrex." + particle_it_name + " (";
122  if( !pti.isValid() ) { r.append("in"); }
123  r.append("valid)>");
124  return r;
125  }
126  )
127  .def(py::init<container&, int>(),
128  py::arg("particle_container"), py::arg("level"))
129  //.def(py::init<container&, int, MFItInfo&>(),
130  // py::arg("particle_container"), py::arg("level"), py::arg("info"))
131  .def_property_readonly_static("is_soa_particle", [](const py::object&){ return ParticleType::is_soa_particle;})
132  ;
133 }
134 
135 template <typename T_ParticleType, int T_NArrayReal=0, int T_NArrayInt=0>
136 void make_ParticleInitData (py::module &m) {
137  using namespace amrex;
138 
139  using ParticleType = T_ParticleType;
141  // depends on https://github.com/AMReX-Codes/amrex/pull/3280
142  // using ParticleInitData = ParticleInitType<ParticleType, T_NArrayReal, T_NArrayInt>;
143 
144  std::string const suffix = particle_type_suffix<T_ParticleType, T_NArrayReal, T_NArrayInt>();
145  auto const particle_init_data_type =
146  std::string("ParticleInitType_") + suffix;
147  auto py_particle_init_data = py::class_<ParticleInitData>(m, particle_init_data_type.c_str())
148  .def(py::init<>())
149  .def_property_readonly_static("is_soa_particle", [](const py::object&){return ParticleType::is_soa_particle;})
150  .def_readwrite("real_array_data", &ParticleInitData::real_array_data)
151  .def_readwrite("int_array_data", &ParticleInitData::int_array_data)
152  ;
153 
154  // only legacy particle has an AoS data structure for positions and id+cpu
155  if constexpr (!ParticleType::is_soa_particle)
156  py_particle_init_data
157  .def_readwrite("real_struct_data", &ParticleInitData::real_struct_data)
158  .def_readwrite("int_struct_data", &ParticleInitData::int_struct_data);
159 }
160 
161 template <typename T_ParticleType, int T_NArrayReal=0, int T_NArrayInt=0,
162  template<class> class Allocator=amrex::DefaultAllocator>
163 void make_ParticleContainer_and_Iterators (py::module &m, std::string allocstr)
164 {
165  using namespace amrex;
166 
167  using ParticleType = T_ParticleType;
168  using ParticleContainerType = ParticleContainer_impl<
169  ParticleType, T_NArrayReal, T_NArrayInt,
170  Allocator
171  >;
172  using ParticleInitData = typename ParticleContainerType::ParticleInitData;
173  using ParticleTileType = typename ParticleContainerType::ParticleTileType;
174 
175  std::string const suffix = particle_type_suffix<T_ParticleType, T_NArrayReal, T_NArrayInt>();
176  auto const particle_container_type = std::string("ParticleContainer_") + suffix + "_" + allocstr;
177  auto py_pc = py::class_<ParticleContainerType>(m, particle_container_type.c_str())
178  .def(py::init())
179  .def(py::init<const Geometry&, const DistributionMapping&, const BoxArray&>())
180  .def(py::init<const Vector<Geometry>&,
182  const Vector<BoxArray>&,
183  const Vector<int>&>())
184  .def(py::init<const Vector<Geometry>&,
186  const Vector<BoxArray>&,
187  const Vector<IntVect>&>())
188 
189  .def_property_readonly_static("is_soa_particle", [](const py::object&){return ParticleType::is_soa_particle;})
190  .def_property_readonly_static("num_struct_real", [](const py::object&){return ParticleContainerType::NStructReal; })
191  .def_property_readonly_static("num_struct_int", [](const py::object&){return ParticleContainerType::NStructInt; })
192  .def_property_readonly_static("num_array_real", [](const py::object&){return ParticleContainerType::NArrayReal; })
193  .def_property_readonly_static("num_array_int", [](const py::object&){return ParticleContainerType::NArrayInt; })
194 
195  .def_property_readonly("num_real_comps", &ParticleContainerType::NumRealComps,
196  "The number of compile-time and runtime Real components in SoA")
197  .def_property_readonly("num_int_comps", &ParticleContainerType::NumIntComps,
198  "The number of compile-time and runtime int components in SoA")
199  .def_property_readonly("num_runtime_real_comps", &ParticleContainerType::NumRuntimeRealComps,
200  "The number of runtime Real components in SoA")
201  .def_property_readonly("num_runtime_int_comps", &ParticleContainerType::NumRuntimeIntComps,
202  "The number of runtime Int components in SoA")
203 
204  .def_property_readonly("num_position_components", [](const py::object&){ return AMREX_SPACEDIM; })
205  .def_property_readonly("byte_spread", &ParticleContainerType::ByteSpread)
206 
207  // runtime components
208  .def("add_real_comp", &ParticleContainerType::template AddRealComp<bool>,
209  py::arg("communicate")=true, "add a new runtime component with type Real")
210  .def("add_int_comp", &ParticleContainerType::template AddIntComp<bool>,
211  py::arg("communicate")=true, "add a new runtime component with type Int")
212 
213  .def_property_readonly("finest_level", &ParticleContainerBase::finestLevel)
214 
215  // ParticleContainer ( const ParticleContainer &) = delete;
216  // ParticleContainer& operator= ( const ParticleContainer & ) = delete;
217 
218  // ParticleContainer ( ParticleContainer && ) = default;
219  // ParticleContainer& operator= ( ParticleContainer && ) = default;
220 
221  .def("Define",
222  py::overload_cast<const Geometry&,
223  const DistributionMapping&,
224  const BoxArray&>
225  (&ParticleContainerType::Define))
226 
227  .def("Define",
228  py::overload_cast<const Vector<Geometry>&,
230  const Vector<BoxArray>&,
231  const Vector<int>&>
232  (&ParticleContainerType::Define))
233 
234  .def("Define",
235  py::overload_cast<const Vector<Geometry>&,
237  const Vector<BoxArray>&,
238  const Vector<IntVect>&>
239  (&ParticleContainerType::Define))
240 
241  .def("num_local_tiles_at_level", &ParticleContainerType::numLocalTilesAtLevel)
242 
243  .def("reserve_data", &ParticleContainerType::reserveData)
244  .def("resize_data", &ParticleContainerType::resizeData)
245 
246  // void InitFromAsciiFile (const std::string& file, int extradata,
247  // const IntVect* Nrep = nullptr);
248 
249  // void InitFromBinaryFile (const std::string& file, int extradata);
250 
251  // void InitFromBinaryMetaFile
252  // void InitRandom (Long icount, ULong iseed,
253  // const ParticleInitData& mass,
254  // bool serialize = false, RealBox bx = RealBox());
255 
256  .def("increment", &ParticleContainerType::Increment) // TODO pure SoA
257  //.def("IncrementWithTotal", &ParticleContainerType::IncrementWithTotal, py::arg("mf"), py::arg("level"), py::arg("local")=false) // TODO pure SoA
258  .def("redistribute", &ParticleContainerType::Redistribute, py::arg("lev_min")=0, py::arg("lev_max")=-1,
259  py::arg("nGrow")=0, py::arg("local")=0, py::arg("remove_negative")=true)
260  .def("sort_particles_by_cell", &ParticleContainerType::SortParticlesByCell)
261  .def("sort_particles_by_bin", &ParticleContainerType::SortParticlesByBin)
262  .def("OK", &ParticleContainerType::OK, py::arg("lev_min") = 0, py::arg("lev_max") = -1, py::arg("nGrow")=0)
263  .def("print_capacity", &ParticleContainerType::PrintCapacity)
264  .def("shrink_t_fit", &ParticleContainerType::ShrinkToFit)
265  // Long NumberOfParticlesAtLevel (int level, bool only_valid = true, bool only_local = false) const;
266  .def("number_of_particles_at_level", &ParticleContainerType::NumberOfParticlesAtLevel,
267  py::arg("level"), py::arg("only_valid")=true, py::arg("only_local")=false)
268  // Vector<Long> NumberOfParticlesInGrid (int level, bool only_valid = true, bool only_local = false) const;
269  .def("number_of_particles_in_grid", &ParticleContainerType::NumberOfParticlesInGrid,
270  py::arg("level"), py::arg("only_valid")=true, py::arg("only_local")=false)
271  // .def("DefineAndReturnParticleTile",
272  // py::overload_cast<int, int, int>
273  // (&ParticleContainerType::DefineAndReturnParticleTile))
274  // Long TotalNumberOfParticles (bool only_valid=true, bool only_local=false) const;
275  .def("total_number_of_particles", &ParticleContainerType::TotalNumberOfParticles,
276  py::arg("only_valid")=true, py::arg("only_local")=false)
277  .def("remove_particles_at_level", &ParticleContainerType::RemoveParticlesAtLevel)
278  .def("remove_particles_not_at_finestLevel", &ParticleContainerType::RemoveParticlesNotAtFinestLevel)
279  // void CreateVirtualParticles (int level, AoS& virts) const;
280  //.def("CreateVirtualParticles", py::overload_cast<int, AoS&>(&ParticleContainerType::CreateVirtualParticles, py::const_),
281  // py::arg("level"), py::arg("virts"))
282  //.def("CreateVirtualParticles", py::overload_cast<int, ParticleTileType&>(&ParticleContainerType::CreateVirtualParticles, py::const_),
283  // py::arg("level"), py::arg("virts")) // TODO pure SoA
284  //.def("CreateGhostParticles", py::overload_cast<int, int, AoS&>(&ParticleContainerType::CreateGhostParticles, py::const_),
285  // py::arg("level"), py::arg("ngrow"), py::arg("ghosts"))
286  //.def("CreateGhostParticles", py::overload_cast<int, int, ParticleTileType&>(&ParticleContainerType::CreateGhostParticles, py::const_),
287  // py::arg("level"), py::arg("ngrow"), py::arg("ghosts")) // TODO pure SoA
288  //.def("add_particles_at_level", py::overload_cast<AoS&, int, int>(&ParticleContainerType::AddParticlesAtLevel),
289  // py::arg("particles"), py::arg("level"), py::arg("ngrow")=0)
290  .def("add_particles_at_level", py::overload_cast<ParticleTileType&, int, int>(&ParticleContainerType::AddParticlesAtLevel),
291  py::arg("particles"), py::arg("level"), py::arg("ngrow")=0)
292 
293  .def("clear_particles", &ParticleContainerType::clearParticles)
294  // template <class PCType,
295  // std::enable_if_t<IsParticleContainer<PCType>::value, int> foo = 0>
296  // void copyParticles (const PCType& other, bool local=false);
297  // template <class PCType,
298  // std::enable_if_t<IsParticleContainer<PCType>::value, int> foo = 0>
299  // void addParticles (const PCType& other, bool local=false);
300  // template <class F, class PCType,
301  // std::enable_if_t<IsParticleContainer<PCType>::value, int> foo = 0,
302  // std::enable_if_t<! std::is_integral<F>::value, int> bar = 0>
303  // void copyParticles (const PCType& other, F&&f, bool local=false);
304  // template <class F, class PCType,
305  // std::enable_if_t<IsParticleContainer<PCType>::value, int> foo = 0,
306  // std::enable_if_t<! std::is_integral<F>::value, int> bar = 0>
307  // void addParticles (const PCType& other, F&& f, bool local=false);
308  // void WriteParticleRealData (void* data, size_t size, std::ostream& os) const;
309  // // void ReadParticleRealData (void* data, size_t size, std::istream& is);
310  // void Checkpoint (const std::string& dir, const std::string& name,
311  // const Vector<std::string>& real_comp_names = Vector<std::string>(),
312  // const Vector<std::string>& int_comp_names = Vector<std::string>()) const
313  // void CheckpointPre ();
314  // void CheckpointPost ();
315  // void Restart (const std::string& dir, const std::string& file);
316  // void Restart (const std::string& dir, const std::string& file, bool is_checkpoint);
317 
318  .def("write_plotfile",
319  //py::overload_cast<std::string const &, std::string const &>(&ParticleContainerType::WritePlotFile, py::const_),
320  [](ParticleContainerType const & pc, std::string const & dir, std::string const & name){
321  return pc.WritePlotFile(dir, name);
322  },
323  py::arg("dir"), py::arg("name")
324  )
325  // template <class F, typename std::enable_if<!std::is_same<F, Vector<std::string>&>::value>::type* = nullptr>
326  // void WritePlotFile (const std::string& dir, const std::string& name, F&& f) const;
327  // void WritePlotFile (const std::string& dir, const std::string& name,
328  // const Vector<std::string>& real_comp_names,
329  // const Vector<std::string>& int_comp_names) const;
330  // void WritePlotFile (const std::string& dir, const std::string& name,
331  // const Vector<std::string>& real_comp_names) const;
332  // void WritePlotFile (const std::string& dir,
333  // const std::string& name,
334  // const Vector<int>& write_real_comp,
335  // const Vector<int>& write_int_comp) const;
336  // void WritePlotFile (const std::string& dir,
337  // const std::string& name,
338  // const Vector<int>& write_real_comp,
339  // const Vector<int>& write_int_comp,
340  // const Vector<std::string>& real_comp_names,
341  // const Vector<std::string>& int_comp_names) const;
342  // void WritePlotFilePre ();
343 
344  // void WritePlotFilePost ();
345  //.def("get_particles", py::overload_cast<>(&ParticleContainerType::GetParticles), py::return_value_policy::reference_internal)
346  .def("get_particles", py::overload_cast<int>(&ParticleContainerType::GetParticles), py::return_value_policy::reference_internal, py::arg("level"))
347  // .def("ParticlesAt", py::overload_cast<int,int,int>(&ParticleContainerType::ParticlesAt),
348  // py::return_value_policy::reference_internal)
349  // .def("ParticlesAt", py::overload_cast<int,int,int>(&ParticleContainerType::ParticlesAt,py::const_))
350  // .def("ParticlesAt", [](ParticleContainerType& pc, int lev, int grid, int tile) {
351  // return pc.ParticlesAt(lev, grid, tile);
352  // }, py::return_value_policy::reference_internal)
353  // const ParticleTileType& ParticlesAt (int lev, int grid, int tile) const
354  // { return m_particles[lev].at(std::make_pair(grid, tile)); }"Return the ParticleTile for level "lev", grid "grid" and tile "tile."
355  // * Const version.
356  // *
357  // * Here, grid and tile are integers that give the index and LocalTileIndex
358  // * of the tile you want.
359  // *
360  // * This is a runtime error if a ParticleTile at "grid" and "tile" has not been
361  // * created yet.
362  // *
363  // * The ParticleLevel must already exist, meaning that the "resizeData()"
364  // * method of this ParticleContainer has been called."
365  // ParticleTileType& ParticlesAt (int lev, int grid, int tile)
366  // { return m_particles[lev].at(std::make_pair(grid, tile)); }
367  // template <class Iterator>
368  // const ParticleTileType& ParticlesAt (int lev, const Iterator& iter) const
369  // { return ParticlesAt(lev, iter.index(), iter.LocalTileIndex()); }
370  // template <class Iterator>
371  // ParticleTileType& ParticlesAt (int lev, const Iterator& iter)
372  // { return ParticlesAt(lev, iter.index(), iter.LocalTileIndex()); }
373  // .def("DefineAndReturnParticleTile", py::overload_cast<int,int,int>(&ParticleContainerType::DefineAndReturnParticleTile))
374  // .def("DefineAndReturnParticleTile", py::overload_cast<int,int,int>(&ParticleContainerType::DefineAndReturnParticleTile, py::const_))
375  /*
376  .def("DefineAndReturnParticleTile",
377  [](ParticleContainerType& pc,
378  int lev,
379  int grid,
380  int tile) {
381  return pc.DefineAndReturnParticleTile(lev,grid,tile);
382  })
383  */
384  // ParticleTileType& DefineAndReturnParticleTile (int lev, int grid, int tile)
385  // {
386  // m_particles[lev][std::make_pair(grid, tile)].define(NumRuntimeRealComps(), NumRuntimeIntComps());
387  // return ParticlesAt(lev, grid, tile);
388  // }
389  // template <class Iterator>
390  // ParticleTileType& DefineAndReturnParticleTile (int lev, const Iterator& iter)
391  // {
392  // auto index = std::make_pair(iter.index(), iter.LocalTileIndex());
393  // m_particles[lev][index].define(NumRuntimeRealComps(), NumRuntimeIntComps());
394  // return ParticlesAt(lev, iter);
395  // }
396  ;
397 
398  py_pc
399  .def("init_random", py::overload_cast<Long, ULong, const ParticleInitData&, bool, RealBox>(&ParticleContainerType::InitRandom))
400  ;
401 
402  // TODO for pure SoA
403  // depends on https://github.com/AMReX-Codes/amrex/pull/3280
404  if constexpr (!T_ParticleType::is_soa_particle) {
405  py_pc
406  .def("init_random_per_box", py::overload_cast<Long, ULong, const ParticleInitData&>(&ParticleContainerType::InitRandomPerBox))
407  .def("init_one_per_cell", &ParticleContainerType::InitOnePerCell)
408  ;
409  }
410 
412  make_Iterators< false, iterator, Allocator >(m, allocstr);
414  make_Iterators< true, const_iterator, Allocator >(m, allocstr);
415 
416  // simpler particle iterator loops: return types of this particle box
417  py_pc
418  .def_property_readonly_static("iterator", [](py::object /* pc */){ return py::type::of<iterator>(); },
419  "amrex iterator for particle boxes")
420  .def_property_readonly_static("const_iterator", [](py::object /* pc */){ return py::type::of<const_iterator>(); },
421  "amrex constant iterator for particle boxes (read-only)")
422  ;
423 }
424 
427 template <typename T_ParticleType, int T_NArrayReal=0, int T_NArrayInt=0>
429 {
430  if constexpr (T_ParticleType::is_soa_particle) {
431  make_Particle<T_NArrayReal, T_NArrayInt>(m);
432  make_StructOfArrays<T_NArrayReal, T_NArrayInt, true> (m);
433  } else {
434 
435  make_Particle< // particle
436  T_ParticleType::NReal,
437  T_ParticleType::NInt
438  >(m);
439  make_Particle< // superparticle
440  T_ParticleType::NReal + T_NArrayReal,
441  T_ParticleType::NInt + T_NArrayInt
442  >(m);
443 
444  make_ArrayOfStructs<T_ParticleType::NReal, T_ParticleType::NInt> (m);
445  make_StructOfArrays<T_NArrayReal, T_NArrayInt> (m);
446  }
447 
448  make_ParticleTile<T_ParticleType, T_NArrayReal, T_NArrayInt> (m);
449 
450  make_ParticleInitData<T_ParticleType, T_NArrayReal, T_NArrayInt>(m);
451 
452  // first, because used as copy target in methods in containers with other allocators
453  make_ParticleContainer_and_Iterators<T_ParticleType, T_NArrayReal, T_NArrayInt,
454  amrex::PinnedArenaAllocator>(m, "pinned");
455 
456  // see Src/Base/AMReX_GpuContainers.H
457  // !AMREX_USE_GPU: DefaultAllocator = std::allocator
458  // AMREX_USE_GPU: DefaultAllocator = amrex::ArenaAllocator
459 
460  // work-around for https://github.com/pybind/pybind11/pull/4581
461  //make_ParticleContainer_and_Iterators<T_ParticleType, T_NArrayReal, T_NArrayInt,
462  // std::allocator>(m, "std"); // CPU DefaultAllocator
463  //make_ParticleContainer_and_Iterators<T_ParticleType, T_NArrayReal, T_NArrayInt,
464  // amrex::ArenaAllocator>(m, "arena"); // GPU DefaultAllocator
465 #ifdef AMREX_USE_GPU
466  make_ParticleContainer_and_Iterators<T_ParticleType, T_NArrayReal, T_NArrayInt,
467  std::allocator>(m, "std");
468  make_ParticleContainer_and_Iterators<T_ParticleType, T_NArrayReal, T_NArrayInt,
469  amrex::DefaultAllocator>(m, "default"); // amrex::ArenaAllocator
470 #else
471  make_ParticleContainer_and_Iterators<T_ParticleType, T_NArrayReal, T_NArrayInt,
472  amrex::DefaultAllocator>(m, "default"); // std::allocator
473  make_ParticleContainer_and_Iterators<T_ParticleType, T_NArrayReal, T_NArrayInt,
474  amrex::ArenaAllocator>(m, "arena");
475 #endif
476  // end work-around
477 #ifdef AMREX_USE_GPU
478  make_ParticleContainer_and_Iterators<T_ParticleType, T_NArrayReal, T_NArrayInt,
479  amrex::DeviceArenaAllocator>(m, "device");
480  make_ParticleContainer_and_Iterators<T_ParticleType, T_NArrayReal, T_NArrayInt,
481  amrex::ManagedArenaAllocator>(m, "managed");
482  make_ParticleContainer_and_Iterators<T_ParticleType, T_NArrayReal, T_NArrayInt,
483  amrex::AsyncArenaAllocator>(m, "async");
484 #endif
485 }
void make_Particle(py::module &m)
Definition: Particle.H:39
void make_Iterators(py::module &m, std::string allocstr)
Definition: ParticleContainer.H:101
void make_Base_Iterators(py::module &m, std::string allocstr)
Definition: ParticleContainer.H:48
void make_ParticleContainer_and_Iterators(py::module &m, std::string allocstr)
Definition: ParticleContainer.H:163
void make_ParticleInitData(py::module &m)
Definition: ParticleContainer.H:136
std::string particle_type_suffix()
Definition: ParticleContainer.H:31