11#include "CellList_def.hpp"
12#include "Vector/map_vector.hpp"
13#include "CellDecomposer.hpp"
14#include "Space/SpaceBox.hpp"
15#include "util/mathutil.hpp"
16#include "CellNNIterator.hpp"
17#include "Space/Shape/HyperCube.hpp"
18#include "CellListNNIteratorRadius.hpp"
19#include <unordered_map>
21#include "CellListIterator.hpp"
22#include "ParticleIt_Cells.hpp"
23#include "ParticleItCRS_Cells.hpp"
24#include "util/common.hpp"
26#include "NN/Mem_type/MemFast.hpp"
27#include "NN/Mem_type/MemBalanced.hpp"
28#include "NN/Mem_type/MemMemoryWise.hpp"
29#include "NN/CellList/NNc_array.hpp"
30#include "cuda/CellList_cpu_ker.cuh"
33template<
typename key,
typename val>
38#ifdef HAVE_LIBQUADMATH
40#include <boost/multiprecision/float128.hpp>
52#define CELL_REALLOC 16ul
54#define STARTING_NSLOT 16
68 typedef typename generate_array<size_t,dim, Fill_zero>::result NNzero;
69 typedef typename generate_array<size_t,dim, Fill_two>::result NNtwo;
77 for (
size_t i = 0 ; i < dim ; i++)
84 for (
size_t i = 0; i < dim; i++)
87 size_t middle = gs.LinId(src_);
90 while (gr_sub3.isNext())
92 auto dst = gr_sub3.get();
95 if ((
long int)middle > gs.LinId(dst))
103 for (
size_t i = 0 ; i < dim; i++)
108 dst.set_d(i,dst.get(i) + 1);
134 typedef typename generate_array<size_t,dim, Fill_zero>::result NNzero;
135 typedef typename generate_array<size_t,dim, Fill_two>::result NNtwo;
143 for (
size_t i = 0 ; i < dim ; i++)
150 for (
size_t i = 0; i < dim; i++)
153 size_t middle = gs.LinId(src_);
156 while (gr_sub3.isNext())
158 auto dst = gr_sub3.get();
160 if ((
long int)middle > gs.LinId(dst))
185 typedef typename generate_array<size_t,dim, Fill_zero>::result NNzero;
186 typedef typename generate_array<size_t,dim, Fill_two>::result NNtwo;
194 for (
size_t i = 0 ; i < dim ; i++)
201 for (
size_t i = 0; i < dim; i++)
205 while (gr_sub3.isNext())
207 auto dst = gr_sub3.get();
249template<
unsigned int dim,
typename T>
253 size_t n_cell_mid[dim];
257 for (
size_t i = 0 ; i < dim ; i++)
259 n_cell[i] = 2*(std::ceil(r_cut / spacing.
get(i)))+1;
260 n_cell_mid[i] = n_cell[i] / 2;
268 for (
unsigned int i = 0 ; i < dim ; i++)
270 cell_zero.
setLow(i,n_cell_mid[i]*spacing.
get(i));
271 cell_zero.
setHigh(i,(n_cell_mid[i]+1)*spacing.
get(i));
275 while (gkdi.isNext())
277 auto key = gkdi.get();
281 for (
unsigned int i = 0 ; i < dim ; i++)
283 cell.
setLow(i,key.get(i)*spacing.
get(i));
284 cell.
setHigh(i,(key.get(i)+1)*spacing.
get(i));
288 T min_distance = cell.min_distance(cell_zero);
289 if (min_distance > r_cut)
292 for (
size_t i = 0 ; i < dim ; i++)
293 {key.set_d(i,key.get(i) - n_cell_mid[i]);}
295 NNcell.add(gs.
LinId(key));
355template<
unsigned int dim,
typename T,
typename Mem_type,
typename transform = no_transform<dim,T>,
typename vector_pos_type = openfpm::vector<Po
int<dim,T>>>
356class CellList :
public CellDecomposer_sm<dim,T,transform>,
public Mem_type
396 Mem_type::init_to_zero(slot,tot_n_cell);
405 void setCellDecomposer(CellDecomposer_sm<dim,T,transform> & cd,
const CellDecomposer_sm<dim,T,transform> & cd_sm,
const Box<dim,T> & dom_box,
size_t pad)
const
409 for (
size_t i = 0 ; i < dim ; i++)
410 {bc[i] = NON_PERIODIC;}
417 for (
size_t i = 0 ; i < dim ; i++)
420 div_big[i] = cd_sm.getDiv()[i] - 2*cd_sm.getPadding(i);
423 cd.setDimensions(cd_sm.getDomain(),div_big,div, pad, bx.
getP1());
440 typedef vector_pos_type internal_vector_pos_type;
449 return CellDecomposer_sm<dim,T,transform>::getGrid();
465 void Initialize(CellDecomposer_sm<dim,T,transform> & cd_sm,
const Box<dim,T> & dom_box,
const size_t pad = 1,
size_t slot=STARTING_NSLOT)
468 for (
size_t i = 0 ; i < dim ; i++) {bc[i] = NON_PERIODIC;}
472 setCellDecomposer(*
this,cd_sm,dom_box,pad);
474 size_t div_w_pad[dim];
477 for (
size_t i = 0 ; i < dim ; i++)
480 tot_cell *= div_w_pad[i];
499 void Initialize(
const Box<dim,T> & box,
const size_t (&div)[dim],
const size_t pad = 1,
size_t slot=STARTING_NSLOT)
520 CellDecomposer_sm<dim,T,transform>::setDimensions(box,div, mat, pad);
521 Mem_type::set_slot(slot);
532 :Mem_type(STARTING_NSLOT)
537 :Mem_type(STARTING_NSLOT)
544 :Mem_type(STARTING_NSLOT)
560 :Mem_type(slot),CellDecomposer_sm<dim,T,transform>(box,div,mat,box.getP1(),pad)
574 CellList(
Box<dim,T> & box,
const size_t (&div)[dim],
const size_t pad = 1,
size_t slot=STARTING_NSLOT)
575 :Mem_type(slot),
n_dec(0)
605 CellList(CellDecomposer_sm<dim,T,transform> & cd_sm,
const Box<dim,T> & box,
const size_t pad = 1,
size_t slot=STARTING_NSLOT)
606 :Mem_type(slot),
n_dec(0)
627 std::copy(&cell.NNc_full[0],&cell.NNc_full[openfpm::math::pow(3,dim)],&
NNc_full[0]);
628 std::copy(&cell.NNc_sym[0],&cell.NNc_sym[openfpm::math::pow(3,dim)/2+1],&
NNc_sym[0]);
630 Mem_type::swap(
static_cast<Mem_type &&
>(cell));
632 static_cast<CellDecomposer_sm<dim,T,transform> &
>(*this).swap(cell);
652 Mem_type::operator=(
static_cast<const Mem_type &
>(cell));
654 static_cast<CellDecomposer_sm<dim,T,transform> &
>(*this) =
static_cast<const CellDecomposer_sm<dim,T,transform> &
>(cell);
669 template<
typename Mem_type2>
672 NNc_full = cell.private_get_NNc_full();
673 NNc_sym = cell.private_get_NNc_sym();
675 Mem_type::copy_general(
static_cast<const Mem_type2 &
>(cell));
677 static_cast<CellDecomposer_sm<dim,T,transform> &
>(*this) =
static_cast<const CellDecomposer_sm<dim,T,transform> &
>(cell);
680 from_cd = cell.private_get_from_cd();
715 inline void addCell(
size_t cell_id,
typename Mem_type::local_index_type
ele)
717 Mem_type::addCell(cell_id,
ele);
726 inline void add(
const T (& pos)[dim],
typename Mem_type::local_index_type
ele)
729 size_t cell_id = this->getCell(pos);
731 Mem_type::add(cell_id,
ele);
743 size_t cell_id = this->getCell(pos);
745 Mem_type::add(cell_id,
ele);
757 inline void addDom(
const T (& pos)[dim],
typename Mem_type::local_index_type
ele)
761 size_t cell_id = this->getCellDom(pos);
780 size_t cell_id = this->getCellDom(pos);
795 inline void addPad(
const T (& pos)[dim],
typename Mem_type::local_index_type
ele)
799 size_t cell_id = this->getCellPad(pos);
818 size_t cell_id = this->getCell(pos);
833 Mem_type::remove(cell,
ele);
842 return Mem_type::size();
854 return Mem_type::getNelements(cell_id);
867 inline auto get(
size_t cell,
size_t ele) ->
decltype(this->Mem_type::get(cell,
ele))
869 return Mem_type::get(cell,
ele);
882 inline auto get(
size_t cell,
size_t ele)
const ->
decltype(this->Mem_type::get(cell,
ele))
884 return Mem_type::get(cell,
ele);
897 Mem_type::swap(
static_cast<Mem_type &
>(cl));
899 static_cast<CellDecomposer_sm<dim,T,transform> &
>(*this).swap(
static_cast<CellDecomposer_sm<dim,T,transform> &
>(cl));
963 template<
unsigned int impl=NO_CHECK>
981 template<
unsigned int impl=NO_CHECK>
987 {NNcalc_rad(r_cut,NNc,this->getCellBox(),this->
getGrid());}
1016 template<
unsigned int impl>
1018 getNNIteratorSym(
size_t cell,
size_t p,
const vector_pos_type & v)
1022 {std::cerr << __FILE__ <<
":" << __LINE__ <<
" Warning when you try to get a symmetric neighborhood iterator, you must construct the Cell-list in a symmetric way" << std::endl;}
1025 CellNNIteratorSym<dim,CellList<dim,T,Mem_type,transform,vector_pos_type>,vector_pos_type,SYM,impl> cln(cell,p,
NNc_sym,*
this,v);
1051 template<
unsigned int impl,
typename vector_pos_type2>
1053 getNNIteratorSymMP(
size_t cell,
size_t p,
const vector_pos_type2 & v_p1,
const vector_pos_type2 & v_p2)
1057 std::cerr << __FILE__ <<
":" << __LINE__ <<
" Warning when you try to get a symmetric neighborhood iterator, you must construct the Cell-list in a symmetric way" << std::endl;
1060 CellNNIteratorSymMP<dim,CellList<dim,T,Mem_type,transform,vector_pos_type>,vector_pos_type2,SYM,impl> cln(cell,p,
NNc_sym,*
this,v_p1,v_p2);
1083 return CellDecomposer_sm<dim,T,transform>::getPadding(i);
1094 return CellDecomposer_sm<dim,T,transform>::getPadding();
1110 Mem_type::destroy();
1120 __attribute__((always_inline))
inline const typename Mem_type::local_index_type & getStartId(
typename Mem_type::local_index_type cell_id)
const
1122 return Mem_type::getStartId(cell_id);
1132 __attribute__((always_inline))
inline const typename Mem_type::local_index_type & getStopId(
typename Mem_type::local_index_type cell_id)
const
1134 return Mem_type::getStopId(cell_id);
1144 __attribute__((always_inline))
inline const typename Mem_type::local_index_type & get_lin(
const typename Mem_type::local_index_type * part_id)
const
1146 return Mem_type::get_lin(part_id);
1178 typedef typename Mem_type::local_index_type ids_type;
1179 typedef typename Mem_type::local_index_type cnt_type;
1185 for (
size_t i = 0 ; i < dim ; i++)
1187 spacing_c[i] = CellDecomposer_sm<dim,T,transform>::getCellBox().getHigh(i);
1188 div_c[i] = CellDecomposer_sm<dim,T,transform>::getDiv()[i];
1189 off[i] = CellDecomposer_sm<dim,T,transform>::getPadding(i);
1199 CellDecomposer_sm<dim,T,transform>::getTransform());
1207 Mem_type::hostToDevice();
1212 const NNc_array<dim,(
unsigned int)openfpm::math::pow(3,dim)> & private_get_NNc_full ()
const
1217 const NNc_array<dim,(
unsigned int)openfpm::math::pow(3,dim)/2+1> & private_get_NNc_sym ()
const
1222 bool private_get_from_cd()
const
1241 this->n_dec =
n_dec;
1265template<
unsigned int dim,
typename St>
static inline void cl_param_calculate(
Box<dim, St> & pbox,
size_t (&div)[dim], St r_cut,
const Ghost<dim, St> & enlarge)
1273 for (
size_t i = 0; i < dim; i++)
1275 div[i] =
static_cast<size_t>((pbox.
getP2().get(i) - pbox.
getP1().get(i)) / r_cut);
1290template<
unsigned int dim,
typename St>
static
1291inline void cl_param_calculateSym(
const Box<dim,St> & dom,
1299 for (
size_t i = 0 ; i < dim ; i++)
1305 for (
size_t i = 0 ; i < dim ; i++)
1307 size_t tmp = std::ceil(fabs(g.
getLow(i)) / r_cut);
1308 pad = (pad > tmp)?pad:tmp;
1310 tmp = std::ceil(fabs(g.
getHigh(i)) / r_cut);
1311 pad = (pad > tmp)?pad:tmp;
1314 cd_sm.setDimensions(dom,div,pad);
1327template<
unsigned int dim,
typename St>
1328static inline void cl_param_calculateSym(
const Box<dim,St> & dom,
1335 for (
size_t i = 0 ; i < dim ; i++)
1342 cd_sm.setDimensions(dom,div,pad);
This class represent an N-dimensional box.
Point< dim, T > getP2() const
Get the point p2.
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
__device__ __host__ T getHigh(int i) const
get the high interval of the box
void enlarge(const Box< dim, T > &gh)
Enlarge the box with ghost margin.
void magnify(T mg)
Magnify the box.
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
Point< dim, T > getP1() const
Get the point p1.
__device__ __host__ void setLow(int i, T val)
set the low interval of the box
it iterate through the elements of a cell
Class for FAST cell list implementation.
const NNc_array< dim,(unsigned int) openfpm::math::pow(3, dim)/2+1 > & getNNc_sym() const
Get the symmetric neighborhood.
size_t getNelements(const size_t cell_id) const
Return the number of elements in the cell.
auto get(size_t cell, size_t ele) const -> decltype(this->Mem_type::get(cell, ele))
Get an element in the cell.
wrap_unordered_map< T, openfpm::vector< long int > > rcache
Caching of r_cutoff radius.
NNc_array< dim,(unsigned int) openfpm::math::pow(3, dim)/2+1 > NNc_sym
The array contain the neighborhood of the cell-id in case of symmetric interaction.
const grid_sm< dim, void > & getGrid()
Return the underlying grid information of the cell list.
auto get(size_t cell, size_t ele) -> decltype(this->Mem_type::get(cell, ele))
Get an element in the cell.
void add(const T(&pos)[dim], typename Mem_type::local_index_type ele)
Add an element in the cell list.
CellList< dim, T, Mem_type, transform > & operator=(CellList< dim, T, Mem_type, transform > &&cell)
Constructor from a temporal object.
CellNNIteratorRadius< dim, CellList< dim, T, Mem_type, transform >, impl > getNNIteratorRadius(size_t cell)
Get the Neighborhood iterator.
void addPad(const Point< dim, T > &pos, typename Mem_type::local_index_type ele)
Add an element in the cell list forcing to be in the padding cells.
ParticleIt_Cells< dim, CellList< dim, T, Mem_fast<>, transform > > getDomainIterator(openfpm::vector< size_t > &dom_cells)
Get an iterator over particles following the cell structure.
NNc_array< dim,(unsigned int) openfpm::math::pow(3, dim)> NNc_full
The array contain the neighborhood of the cell-id in case of asymmetric interaction.
Mem_type Mem_type_type
Type of internal memory structure.
void clear()
Clear the cell list.
bool from_cd
True if has been initialized from CellDecomposer.
void InitializeStructures(const size_t(&div)[dim], size_t tot_n_cell, size_t slot=STARTING_NSLOT)
Initialize the structures of the data structure.
void addDom(const Point< dim, T > &pos, typename Mem_type::local_index_type ele)
Add an element in the cell list forcing to be in the domain cells.
__attribute__((always_inline)) inline const typename Mem_type size_t get_gm()
Return the starting point of the cell p.
void set_ndec(size_t n_dec)
Set the n_dec number.
void set_gm(size_t g_m)
Set the ghost marker.
CellList< dim, T, Mem_type, transform, vector_pos_type > & operator=(const CellList< dim, T, Mem_type, transform, vector_pos_type > &cell)
Constructor from a temporal object.
size_t getNCells() const
Get the number of cells this cell-list contain.
CellList(Box< dim, T > &box, const size_t(&div)[dim], Matrix< dim, T > mat, const size_t pad=1, size_t slot=STARTING_NSLOT)
Cell list constructor.
void destroy()
Litterary destroy the memory of the cell list, including the retained one.
__attribute__((always_inline)) inline CellNNIterator< dim
Get the Neighborhood iterator.
size_t(& getPadding())[dim]
Return the number of padding cells of the Cell decomposer as an array.
CellIterator< CellList< dim, T, Mem_type, transform > > getCellIterator(size_t cell)
Get the Cell iterator.
void Initialize(const SpaceBox< dim, T > &box, const size_t(&div)[dim], const size_t pad=1, size_t slot=STARTING_NSLOT)
__attribute__((always_inline)) inline CellNNIteratorSymMP< dim
Get the symmetric Neighborhood iterator.
void swap(CellList< dim, T, Mem_type, transform, vector_pos_type > &cl)
Swap the memory.
void Initialize(const Box< dim, T > &box, const size_t(&div)[dim], const size_t pad=1, size_t slot=STARTING_NSLOT)
__attribute__((always_inline)) inline CellNNIteratorSym< dim
Get the symmetric Neighborhood iterator.
CellList< dim, T, Mem_type, transform, vector_pos_type > & operator=(const CellList< dim, T, Mem_type2, transform, vector_pos_type > &cell)
Constructor from a temporal object.
void remove(size_t cell, size_t ele)
remove an element from the cell
CellList(CellDecomposer_sm< dim, T, transform > &cd_sm, const Box< dim, T > &box, const size_t pad=1, size_t slot=STARTING_NSLOT)
Cell list constructor from a cell decomposer.
CellList(CellList< dim, T, Mem_type, transform, vector_pos_type > &&cell)
Copy constructor.
void addDom(const T(&pos)[dim], typename Mem_type::local_index_type ele)
Add an element in the cell list forcing to be in the domain cells.
void setRadius(T radius)
Set the radius for the getNNIteratorRadius.
size_t getPadding(size_t i) const
Return the number of padding cells of the Cell decomposer.
T stype
Type of the coordinate space (double float)
CellList(const CellList< dim, T, Mem_type, transform, vector_pos_type > &cell)
Copy constructor.
size_t get_ndec() const
Set the n_dec number.
void addPad(const T(&pos)[dim], typename Mem_type::local_index_type ele)
Add an element in the cell list forcing to be in the padding cells.
CellList(Box< dim, T > &box, const size_t(&div)[dim], const size_t pad=1, size_t slot=STARTING_NSLOT)
Cell list constructor.
void add(const Point< dim, T > &pos, typename Mem_type::local_index_type ele)
Add an element in the cell list.
__attribute__((always_inline)) inline CellNNIteratorRadius< dim
Get the symmetric Neighborhood iterator.
void Initialize(CellDecomposer_sm< dim, T, transform > &cd_sm, const Box< dim, T > &dom_box, const size_t pad=1, size_t slot=STARTING_NSLOT)
CellList()
Default Constructor.
openfpm::vector< long int > nnc_rad
Cells for the neighborhood radius.
Mem_type::local_index_type value_type
Object type that the structure store.
void addCell(size_t cell_id, typename Mem_type::local_index_type ele)
Add to the cell.
CellList(SpaceBox< dim, T > &box, const size_t(&div)[dim], const size_t pad=1, size_t slot=STARTING_NSLOT)
Cell list constructor.
Iterator for the neighborhood of the cell structures with free radius.
Symmetric iterator for the neighborhood of the cell structures.
Symmetric iterator for the neighborhood of the cell structures.
Iterator for the neighborhood of the cell structures.
This class implement an NxN (dense) matrix.
void swap(NNc_array< dim, size, thr > &nnc)
swap NNc_array
void init_sym()
Initialize the NNc array with symmetric neighborhood cells indexes.
void init_full()
Initialize the NNc array with full neighborhood cells indexes.
void set_size(const size_t(&sz)[dim])
Set the size in each.
This iterator iterate across the particles of a Cell-list following the Cell structure.
This class implement the point shape in an N-dimensional space.
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
This class represent an N-dimensional box.
Declaration grid_key_dx_iterator_sub.
grid_key_dx is the key to access any element in the grid
__device__ __host__ void set_d(index_type i, index_type id)
Set the i index.
__device__ __host__ index_type get(index_type i) const
Get the i index.
mem_id LinId(const grid_key_dx< N, ids_type > &gk, const signed char sum_id[N]) const
Linearization of the grid_key_dx with a specified shift.
Implementation of 1-D std::vector like structure.
Wrapper of the unordered map.
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data