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" 33 template<
typename key,
typename val>
38 #ifdef HAVE_LIBQUADMATH 40 #include <boost/multiprecision/float128.hpp> 44 template<
typename val>
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();
249 template<
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));
355 template<
unsigned int dim,
typename T,
typename Mem_type,
typename transform = no_transform<dim,T>,
typename vector_pos_type = openfpm::vector<Po
int<dim,T>>>
356 class 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());
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());}
989 CellNNIteratorRadius<dim,CellList<dim,T,Mem_type,transform,vector_pos_type>,impl> cln(cell,NNc,*
this);
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);
1196 CellDecomposer_sm<dim,T,transform>::getTransform());
1204 Mem_type::hostToDevice();
1209 const NNc_array<dim,(
unsigned int)openfpm::math::pow(3,dim)> & private_get_NNc_full ()
const 1214 const NNc_array<dim,(
unsigned int)openfpm::math::pow(3,dim)/2+1> & private_get_NNc_sym ()
const 1219 bool private_get_from_cd()
const 1238 this->n_dec =
n_dec;
1262 template<
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)
1270 for (
size_t i = 0; i < dim; i++)
1272 div[i] = static_cast<size_t>((pbox.
getP2().get(i) - pbox.
getP1().get(i)) / r_cut);
1287 template<
unsigned int dim,
typename St>
static 1288 inline void cl_param_calculateSym(
const Box<dim,St> & dom,
1296 for (
size_t i = 0 ; i < dim ; i++)
1302 for (
size_t i = 0 ; i < dim ; i++)
1304 size_t tmp = std::ceil(fabs(g.
getLow(i)) / r_cut);
1305 pad = (pad > tmp)?pad:tmp;
1307 tmp = std::ceil(fabs(g.
getHigh(i)) / r_cut);
1308 pad = (pad > tmp)?pad:tmp;
1311 cd_sm.setDimensions(dom,div,pad);
1324 template<
unsigned int dim,
typename St>
1325 static inline void cl_param_calculateSym(
const Box<dim,St> & dom,
1332 for (
size_t i = 0 ; i < dim ; i++)
1339 cd_sm.setDimensions(dom,div,pad);
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.
This class represent an N-dimensional box.
void addCell(size_t cell_id, typename Mem_type::local_index_type ele)
Add to the cell.
CellList(Box< dim, T > &box, const size_t(&div)[dim], const size_t pad=1, size_t slot=STARTING_NSLOT)
Cell list constructor.
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.
size_t get_ndec() const
Set the n_dec number.
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.
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.
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
void clear()
Clear the cell list.
openfpm::vector< long int > nnc_rad
Cells for the neighborhood radius.
void magnify(T mg)
Magnify the box.
Point< dim, T > getP2() const
Get the point p2.
CellList(CellList< dim, T, Mem_type, transform, vector_pos_type > &&cell)
Copy constructor.
__attribute__((always_inline)) inline CellNNIterator< dim
Get the Neighborhood iterator.
void destroy()
Litterary destroy the memory of the cell list, including the retained one.
CellList< dim, T, Mem_type, transform > & operator=(CellList< dim, T, Mem_type, transform > &&cell)
Constructor from a temporal object.
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, vector_pos_type > & operator=(const CellList< dim, T, Mem_type2, transform, vector_pos_type > &cell)
Constructor from a temporal object.
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.
Mem_type::local_index_type value_type
Object type that the structure store.
__device__ __host__ index_type get(index_type i) const
Get the i index.
This class implement the point shape in an N-dimensional space.
Symmetric iterator for the neighborhood of the cell structures.
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 getNelements(const size_t cell_id) const
Return the number of elements in the cell.
const grid_sm< dim, void > & getGrid()
Return the underlying grid information of the cell list.
CellIterator< CellList< dim, T, Mem_type, transform > > getCellIterator(size_t cell)
Get the Cell iterator.
Symmetric iterator for the neighborhood of the cell structures.
void set_size(const size_t(&sz)[dim])
Set the size in each.
Mem_type Mem_type_type
Type of internal memory structure.
void setRadius(T radius)
Set the radius for the getNNIteratorRadius.
const NNc_array< dim,(unsigned int) openfpm::math::pow(3, dim)/2+1 > & getNNc_sym() const
Get the symmetric neighborhood.
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
mem_id LinId(const grid_key_dx< N, ids_type > &gk, const char sum_id[N]) const
Linearization of the grid_key_dx with a specified shift.
size_t getPadding(size_t i) const
Return the number of padding cells of the Cell decomposer.
void add(const Point< dim, T > &pos, typename Mem_type::local_index_type ele)
Add an element in the cell list.
size_t(& getPadding())[dim]
Return the number of padding cells of the Cell decomposer as an array.
size_t getNCells() const
Get the number of cells this cell-list contain.
void set_gm(size_t g_m)
Set the ghost marker.
CellList(const CellList< dim, T, Mem_type, transform, vector_pos_type > &cell)
Copy constructor.
CellNNIteratorRadius< dim, CellList< dim, T, Mem_type, transform >, impl > getNNIteratorRadius(size_t cell)
Get the Neighborhood iterator.
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.
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
void set_ndec(size_t n_dec)
Set the n_dec number.
auto get(size_t cell, size_t ele) const -> decltype(this->Mem_type::get(cell, ele))
Get an element in the cell.
__device__ __host__ void setLow(int i, T val)
set the low interval of the box
void enlarge(const Box< dim, T > &gh)
Enlarge the box with ghost margin.
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.
This class implement an NxN (dense) matrix.
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
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)
it iterate through the elements of a cell
void init_sym()
Initialize the NNc array with symmetric neighborhood cells indexes.
This class represent an N-dimensional box.
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.
T stype
Type of the coordinate space (double float)
bool from_cd
True if has been initialized from CellDecomposer.
CellList()
Default Constructor.
__attribute__((always_inline)) inline const typename Mem_type size_t get_gm()
Return the starting point of the cell p.
This iterator iterate across the particles of a Cell-list following the Cell structure.
void swap(NNc_array< dim, size, thr > &nnc)
swap NNc_array
wrap_unordered_map< T, openfpm::vector< long int > > rcache
Caching of r_cutoff radius.
void swap(CellList< dim, T, Mem_type, transform, vector_pos_type > &cl)
Swap the memory.
void init_full()
Initialize the NNc array with full neighborhood cells indexes.
void Initialize(const SpaceBox< dim, T > &box, const size_t(&div)[dim], const size_t pad=1, size_t slot=STARTING_NSLOT)
void Initialize(const Box< dim, T > &box, const size_t(&div)[dim], const size_t pad=1, size_t slot=STARTING_NSLOT)
CellList(SpaceBox< dim, T > &box, const size_t(&div)[dim], const size_t pad=1, size_t slot=STARTING_NSLOT)
Cell list constructor.
__device__ __host__ void set_d(index_type i, index_type id)
Set the i index.
Iterator for the neighborhood of the cell structures with free radius.
Wrapper of the unordered map.
Implementation of 1-D std::vector like structure.
Class for FAST cell list implementation.
__device__ __host__ T getHigh(int i) const
get the high interval of the box
auto get(size_t cell, size_t ele) -> decltype(this->Mem_type::get(cell, ele))
Get an element in the cell.
Iterator for the neighborhood of the cell structures.
Point< dim, T > getP1() const
Get the point p1.
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.
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 remove(size_t cell, size_t ele)
remove an element from the cell