10 #include <AMReX_Config.H>
21 #include <unordered_set>
30 template<
typename T, std::size_t... I>
32 build_array (T a[], std::index_sequence<I...> s)
34 return std::array<T, s.size()>{a[I]...};
38 template <
int T_NReal,
int T_NInt=0>
52 using namespace amrex;
55 auto const particle_name = std::string(
"Particle_").append(std::to_string(T_NReal) +
"_" + std::to_string(T_NInt));
56 py::class_<ParticleType> (m, particle_name.c_str())
58 .def(py::init([](
AMREX_D_DECL(ParticleReal
x, ParticleReal y, ParticleReal z)) {
59 std::unique_ptr<ParticleType> part(
new ParticleType());
61 #if (AMREX_SPACEDIM >= 2)
64 #if (AMREX_SPACEDIM >= 3)
72 [](
AMREX_D_DECL(ParticleReal
x, ParticleReal y, ParticleReal z), py::args& args)
74 std::unique_ptr<ParticleType> part(
new ParticleType());
75 AMREX_D_TERM(part->m_pos[0] =
x;, part->m_pos[1] = y;, part->m_pos[2] = z;)
76 int T_NTotal = T_NReal + T_NInt;
77 int argn = args.size();
78 if(argn != T_NTotal) {
79 throw std::runtime_error(
"Must supply all " + std::to_string(T_NTotal) +
" rdata, idata elements");
81 if constexpr (T_NReal > 0) {
82 for (
int ii = 0; ii < T_NReal; ii++) {
83 part->m_rdata[ii] = py::cast<ParticleReal>(args[ii]);
86 if constexpr (T_NInt > 0) {
87 for (
int ii = 0; ii < T_NInt; ii++) {
88 part->m_idata[ii] = py::cast<int>(args[ii+T_NReal]);
96 [](
AMREX_D_DECL(ParticleReal
x, ParticleReal y, ParticleReal z), py::kwargs& kwargs)
98 std::unique_ptr<ParticleType> part(
new ParticleType());
99 AMREX_D_TERM(part->m_pos[0] =
x;, part->m_pos[1] = y;, part->m_pos[2] = z;)
101 for (
auto const& item : kwargs) {
102 std::regex component_separator(
"(.*)_([0-9]*)");
104 std::string varname = item.first.cast<std::string>();
105 std::regex_match(varname, sm, component_separator, std::regex_constants::match_default);
106 int comp = std::stoi(sm[2]);
107 if constexpr (T_NReal > 0) {
108 if (comp >= 0 && comp < T_NReal && sm[1] ==
"rdata") {
109 part->m_rdata[comp] = item.second.cast<ParticleReal>();
112 if constexpr (T_NInt > 0) {
113 if (comp >= 0 && comp < T_NInt && sm[1] ==
"idata") {
114 part->m_idata[comp] = item.second.cast<
int>();
123 [](py::kwargs& kwargs) {
124 std::unique_ptr<ParticleType> part(
new ParticleType());
125 for (
auto const& item : kwargs) {
126 std::regex component_separator(
"(.*)_([0-9]*)");
128 std::string varname = item.first.cast<std::string>();
129 std::regex_match(varname, sm, component_separator, std::regex_constants::match_default);
131 if (varname ==
"x") { part->m_pos[0] = item.second.cast<ParticleReal>(); }
132 #if AMREX_SPACEDIM >= 2
133 if (varname ==
"y") { part->m_pos[1] = item.second.cast<ParticleReal>(); }
134 #elif AMREX_SPACEDIM == 3
135 if (varname ==
"z") { part->m_pos[2] = item.second.cast<ParticleReal>(); }
138 comp = std::stoi(sm[2]);
139 if constexpr (T_NReal > 0) {
140 if(comp >= 0 && comp < T_NReal && sm[1] ==
"rdata") {
141 part->m_rdata[comp] = item.second.cast<ParticleReal>();
144 if constexpr (T_NInt > 0) {
145 if (comp >= 0 && comp < T_NInt && sm[1] ==
"idata") {
146 part->m_idata[comp] = item.second.cast<
int>();
155 [](py::object& obj) {
156 py::str py_name = obj.attr(
"__class__").attr(
"__name__");
157 const std::string name = py_name;
158 const auto p = obj.cast<ParticleType>();
161 return "<amrex." + name +
" with attributes\nid cpu pos rdata idata \n" + s.str() +
">";
165 [](
const ParticleType& p) {
170 .def_readonly_static(
"NReal", &ParticleType::NReal)
171 .def_readonly_static(
"NInt", &ParticleType::NInt)
172 .def(
"pos", [](
const ParticleType &p,
int index) {
return p.pos(index); })
173 .def(
"pos", [](
const ParticleType &p) {
return p.pos(); })
174 .def(
"setPos", [](ParticleType &p,
int index, Real val) {
AMREX_ASSERT(index > 0 && index < AMREX_SPACEDIM); p.m_pos[index] = val; })
175 .def(
"setPos", [](ParticleType &p,
const RealVect & vals) {
for (
int ii=0; ii < AMREX_SPACEDIM; ii++) { p.m_pos[ii] = vals[ii]; } })
176 .def(
"setPos", [](ParticleType &p,
const std::array<Real, AMREX_SPACEDIM>& vals) {
for (
int ii=0; ii < AMREX_SPACEDIM; ii++) { p.m_pos[ii] = vals[ii]; } })
178 .def(
"get_rdata", [](ParticleType &p,
int index) {
179 if constexpr (T_NReal > 0) {
180 if(index < 0 || index >= T_NReal) {
181 throw std::range_error(
"index not in range. Valid range : [0, " + std::to_string(T_NReal));
183 return p.m_rdata[index];
190 .def(
"get_rdata", [](ParticleType &p) {
191 if constexpr (T_NReal > 0) {
194 std::make_index_sequence<T_NReal>{}
202 .def(
"set_rdata", [](ParticleType &p,
int index, Real val) {
203 if constexpr (T_NReal > 0) {
204 if(index < 0 || index >= T_NReal) {
206 throw std::range_error(
"index not in range. Valid range : [0, " + std::to_string(T_NReal) +
")");
208 p.m_rdata[index] = val;
214 .def(
"set_rdata", [](ParticleType &p,
const std::array<Real, T_NReal>& vals) {
215 if constexpr (T_NReal > 0) {
216 for (
int ii=0; ii < T_NReal; ii++) {
217 p.m_rdata[ii] = vals[ii];
224 .def(
"get_idata", [](ParticleType &p,
int index) {
225 if constexpr (T_NInt > 0) {
226 if(index < 0 || index >= T_NInt) {
227 throw std::range_error(
"index not in range. Valid range : [0, " + std::to_string(T_NInt));
229 return p.m_idata[index];
236 .def(
"get_idata", [](ParticleType &p) {
237 if constexpr (T_NInt > 0) {
240 std::make_index_sequence<T_NInt>{}
249 .def(
"set_idata", [](ParticleType &p,
int index,
int val) {
250 if constexpr (T_NInt > 0) {
251 if(index < 0 || index >= T_NInt) {
252 throw std::range_error(
"index not in range. Valid range : [0, " + std::to_string(T_NInt) +
")");
254 p.m_idata[index] = val;
260 .def(
"set_idata", [](ParticleType &p,
const std::array<int, T_NInt>& vals) {
261 if constexpr (T_NInt > 0) {
262 for (
int ii=0; ii < T_NInt; ii++) {
263 p.m_idata[ii] = vals[ii];
270 .def(
"cpu", [](
const ParticleType &p) {
const int m_cpu = p.cpu();
return m_cpu; })
271 .def(
"id", [](
const ParticleType &p) {
const int m_id = p.id();
return m_id; })
272 .def(
"NextID", [](
const ParticleType &p) {
return p.NextID();})
273 .def(
"NextID", [](
const ParticleType &p, Long nextid) { p.NextID(nextid); })
274 .def_property(
"x", [](ParticleType &p){
return p.pos(0);}, [](ParticleType &p, Real val){ p.m_pos[0] = val; })
275 #
if AMREX_SPACEDIM >= 2
276 .def_property(
"y", [](ParticleType &p){
return p.pos(1);}, [](ParticleType &p, Real val){ p.m_pos[1] = val; })
278 #
if AMREX_SPACEDIM == 3
279 .def_property(
"z", [](ParticleType &p){
return p.pos(2);}, [](ParticleType &p, Real val){ p.m_pos[2] = val; })
#define AMREX_D_TERM(a, b, c)
#define AMREX_D_DECL(a, b, c)
void make_Particle(py::module &m)
Definition: Particle.H:39
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void ignore_unused(const Ts &...)