diff options
-rwxr-xr-x | Python/pywarpx/_libwarpx.py | 46 | ||||
-rw-r--r-- | Source/Python/WarpXWrappers.H | 4 | ||||
-rw-r--r-- | Source/Python/WarpXWrappers.cpp | 24 |
3 files changed, 74 insertions, 0 deletions
diff --git a/Python/pywarpx/_libwarpx.py b/Python/pywarpx/_libwarpx.py index 817f64da5..9ebbd262f 100755 --- a/Python/pywarpx/_libwarpx.py +++ b/Python/pywarpx/_libwarpx.py @@ -210,6 +210,7 @@ libwarpx.warpx_getGfieldCPLoVects_PML.restype = _LP_c_int libwarpx.warpx_getGfieldFP_PML.restype = _LP_LP_c_real libwarpx.warpx_getGfieldFPLoVects_PML.restype = _LP_c_int libwarpx.warpx_getParticleBoundaryBufferSize.restype = ctypes.c_int +libwarpx.warpx_getParticleBoundaryBufferStructs.restype = _LP_LP_c_particlereal libwarpx.warpx_getParticleBoundaryBuffer.restype = _LP_LP_c_particlereal libwarpx.warpx_getParticleBoundaryBufferScrapedSteps.restype = _LP_LP_c_int @@ -859,6 +860,50 @@ def get_particle_boundary_buffer_size(species_name, boundary): ) +def get_particle_boundary_buffer_structs(species_name, boundary, level): + ''' + + This returns a list of numpy arrays containing the particle struct data + for a species that has been scraped by a specific simulation boundary. The + particle data is represented as a structured numpy array and contains the + particle 'x', 'y', 'z', 'id', and 'cpu'. + + The data for the numpy arrays are not copied, but share the underlying + memory buffer with WarpX. The numpy arrays are fully writeable. + + Parameters + ---------- + + species_name : the species name that the data will be returned for + boundary : the boundary from which to get the scraped particle data. + In the form x/y/z_hi/lo or eb. + level : Which AMR level to retrieve scraped particle data from. + + Returns + ------- + + A List of numpy arrays. + + ''' + + particles_per_tile = _LP_c_int() + num_tiles = ctypes.c_int(0) + data = libwarpx.warpx_getParticleBoundaryBufferStructs( + ctypes.c_char_p(species_name.encode('utf-8')), + _get_boundary_number(boundary), level, + ctypes.byref(num_tiles), ctypes.byref(particles_per_tile) + ) + + particle_data = [] + for i in range(num_tiles.value): + arr = _array1d_from_pointer(data[i], _p_dtype, particles_per_tile[i]) + particle_data.append(arr) + + _libc.free(particles_per_tile) + _libc.free(data) + return particle_data + + def get_particle_boundary_buffer(species_name, boundary, comp_name, level): ''' @@ -879,6 +924,7 @@ def get_particle_boundary_buffer(species_name, boundary, comp_name, level): timestep at which a particle was scraped will be returned. level : Which AMR level to retrieve scraped particle data from. + Returns ------- diff --git a/Source/Python/WarpXWrappers.H b/Source/Python/WarpXWrappers.H index 71eb5b4fd..dd7a648fc 100644 --- a/Source/Python/WarpXWrappers.H +++ b/Source/Python/WarpXWrappers.H @@ -114,6 +114,10 @@ extern "C" { const char* species_name, int boundary, int lev, int* num_tiles, int** particles_per_tile, const char* comp_name); + amrex::ParticleReal** warpx_getParticleBoundaryBufferStructs( + const char* species_name, int boundary, int lev, + int* num_tiles, int** particles_per_tile); + void warpx_clearParticleBoundaryBuffer (); void warpx_ComputeDt (); diff --git a/Source/Python/WarpXWrappers.cpp b/Source/Python/WarpXWrappers.cpp index 9ee99e8ab..66db34497 100644 --- a/Source/Python/WarpXWrappers.cpp +++ b/Source/Python/WarpXWrappers.cpp @@ -607,6 +607,30 @@ extern "C" return data; } + amrex::ParticleReal** warpx_getParticleBoundaryBufferStructs(const char* species_name, int boundary, int lev, + int* num_tiles, int** particles_per_tile) + { + const std::string name(species_name); + auto& particle_buffers = WarpX::GetInstance().GetParticleBoundaryBuffer(); + auto& particle_buffer = particle_buffers.getParticleBuffer(species_name, boundary); + + int i = 0; + for (amrex::ParIter<0,0,PIdx::nattribs, 0, amrex::PinnedArenaAllocator> pti(particle_buffer, lev); pti.isValid(); ++pti, ++i) {} + + // *num_tiles = myspc.numLocalTilesAtLevel(lev); + *num_tiles = i; + *particles_per_tile = (int*) malloc(*num_tiles*sizeof(int)); + + amrex::ParticleReal** data = (amrex::ParticleReal**) malloc(*num_tiles*sizeof(typename WarpXParticleContainer::ParticleType*)); + i = 0; + for (amrex::ParIter<0,0,PIdx::nattribs, 0, amrex::PinnedArenaAllocator> pti(particle_buffer, lev); pti.isValid(); ++pti, ++i) { + auto& aos = pti.GetArrayOfStructs(); + data[i] = (amrex::ParticleReal*) aos.data(); + (*particles_per_tile)[i] = pti.numParticles(); + } + return data; + } + void warpx_clearParticleBoundaryBuffer () { auto& particle_buffers = WarpX::GetInstance().GetParticleBoundaryBuffer(); particle_buffers.clearParticles(); |