Commit 74142cb4 authored by incardon's avatar incardon
Browse files

Merging cell-list work

parents dde50897 313e8ad0
......@@ -11,6 +11,7 @@
#include "Space/SpaceBox.hpp"
#include "Space/Matrix.hpp"
#include "util/copy_compare/meta_compare.hpp"
#include "Grid/grid_sm.hpp"
#define CELL_DECOMPOSER 8001lu
......
This diff is collapsed.
/*
* CellListBal.hpp
*
* Created on: Mar 22, 2015
* Last modified: June 25, 2015
* Authors: Pietro Incardona, Yaroslav Zaluzhnyi
*/
#ifndef CELLLISTBAL_HPP_
#define CELLLISTBAL_HPP_
#include "CellDecomposer.hpp"
#include "Space/SpaceBox.hpp"
#include "util/mathutil.hpp"
#include "CellNNIterator.hpp"
#include "Space/Shape/HyperCube.hpp"
/*! \brief Class for BALANCED cell list implementation
*
* This class implement the BALANCED cell list is fast (not best)
* The memory allocation is small (not best).
* The memory allocation is (in byte) Size = M*16 + N*sizeof(ele)
*
* Where
*
* N = total number of elements
* M = number of cells
* sizeof(ele) = the size of the element the cell list is storing, example if
* the cell list store the particle id (64bit) is 8 byte
*
* \warning Do not use for extremely fine cell list (M big)
*
* \tparam dim Dimensionality of the space
* \tparam T type of the space float, double, complex
*
*/
template<unsigned int dim, typename T, typename base>
class CellList<dim,T,BALANCED,base>: public CellDecomposer_sm<dim,T>
{
// The array contain the neighborhood of the cell-id in case of asymmetric interaction
//
// * * *
// * x *
// * * *
long int NNc_full[openfpm::math::pow(3,dim)];
// The array contain the neighborhood of the cell-id in case of symmetric interaction
//
// * * *
// x *
//
long int NNc_sym[openfpm::math::pow(3,dim)/2+1];
// The array contain the neighborhood of the cell-id in case of symmetric interaction (Optimized)
//
// * *
// x *
//
long int NNc_cr[openfpm::math::pow(2,dim)];
// each cell has a pointer to a dynamic structure
// that store the elements in the cell
openfpm::vector<base> cl_base;
//Origin point
Point<dim,T> orig;
public:
// Object type that the structure store
typedef T value_type;
/*! \brief Return the underlying grid information of the cell list
*
* \return the grid infos
*
*/
grid_sm<dim,void> & getGrid()
{
CellDecomposer_sm<dim,T>::getGrid();
}
/*! Initialize the cell list
*
* \param box Domain where this cell list is living
* \param origin of the Cell list
* \param div grid size on each dimension
*
*/
void Initialize(Box<dim,T> & box, size_t (&div)[dim], Point<dim,T> & orig, const size_t pad = 1)
{
SpaceBox<dim,T> sbox;
Initialize(sbox,div,orig);
}
/*! Initialize the cell list
*
* \param box Domain where this cell list is living
* \param origin of the Cell list
* \param div grid size on each dimension
*
*/
void Initialize(SpaceBox<dim,T> & box, size_t (&div)[dim], Point<dim,T> & orig, const size_t pad = 1)
{
// Add padding
size_t div_pad[dim];
for (size_t i = 0 ; i < dim ; i++)
div_pad[i] = div[i] + 2;
CellDecomposer_sm<dim,T>::setDimensions(box,div_pad, pad);
this->orig = orig;
//resize the vector to needed number of cells
cl_base.resize(this->tot_n_cell);
//filling a vector with "base" structures
for (int i = 0; i < this->tot_n_cell; i++)
//cl_base.push_back(base());
cl_base.get(i) = base();
// Calculate the NNc-arrays (for neighborhood):
// compile-time array {0,0,0,....} and {3,3,3,...}
typedef typename generate_array<size_t,dim, Fill_zero>::result NNzero;
typedef typename generate_array<size_t,dim, Fill_two>::result NNtwo;
typedef typename generate_array<size_t,dim, Fill_one>::result NNone;
// Generate the sub-grid iterator
grid_key_dx_iterator_sub<dim> gr_sub3(this->gr_cell,NNzero::data,NNtwo::data);
// Calculate the NNc array
size_t middle = this->gr_cell.LinId(NNone::data);
size_t i = 0;
while (gr_sub3.isNext())
{
NNc_full[i] = (long int)this->gr_cell.LinId(gr_sub3.get()) - middle;
++gr_sub3;
i++;
}
// Calculate the NNc_sym array
i = 0;
gr_sub3.reset();
while (gr_sub3.isNext())
{
auto key = gr_sub3.get();
size_t lin = this->gr_cell.LinId(key);
// Only the first half is considered
if (lin < middle)
{
++gr_sub3;
continue;
}
NNc_sym[i] = lin - middle;
++gr_sub3;
i++;
}
// Calculate the NNc_cross array
i = 0;
grid_key_dx_iterator_sub<dim> gr_sub2(this->gr_cell,NNzero::data,NNone::data);
while (gr_sub2.isNext())
{
auto key = gr_sub2.get();
NNc_cr[i] = (long int)this->gr_cell.LinId(key);
++gr_sub2;
i++;
}
}
/*! \brief Default constructor
*
*/
CellList()
{
}
/*! \brief Cell list
*
* \param box Domain where this cell list is living
* \param origin of the Cell list
* \param div grid size on each dimension
*
*/
CellList(Box<dim,T> & box, size_t (&div)[dim], Point<dim,T> & orig, const size_t pad = 1)
{
SpaceBox<dim,T> sbox(box);
Initialize(sbox,div,orig,pad);
}
/*! \brief Cell list
*
* \param box Domain where this cell list is living
* \param origin of the Cell list
* \param div grid size on each dimension
*
*/
CellList(SpaceBox<dim,T> & box, size_t (&div)[dim], Point<dim,T> & orig, const size_t pad = 1)
{
Initialize(box,div,orig,pad);
}
/*! \brief Add an element in the cell list
*
* \param pos array that contain the coordinate
* \param ele element to store
*
*/
void add(const T (& pos)[dim], typename base::value_type ele)
{
// calculate the Cell id
size_t cell_id = this->getCell(pos);
// add a new element
cl_base.get(cell_id)->add(ele);
}
/*! \brief Add an element in the cell list
*
* \param pos array that contain the coordinate
* \param ele element to store
*
*/
void add(const Point<dim,T> & pos, typename base::value_type ele)
{
// calculate the Cell id
size_t cell_id = this->getCell(pos);
// add a new element
cl_base.get(cell_id).add(ele);
}
/*! \brief remove an element from the cell
*
* \param cell cell id
* \param ele element id
*
*/
void remove(size_t cell, size_t ele)
{
cl_base.get(cell).remove(ele);
}
/*! \brief Return the number of element in the cell
*
* \param cell_id id of the cell
*
* \return number of elements in the cell
*
*/
size_t getNelements(size_t cell_id)
{
return cl_base.get(cell_id).size();
}
/*! \brief Get an element in the cell
*
* \param cell cell id
* \param ele element id
*
*/
auto get(size_t cell, size_t ele) -> decltype(cl_base.get(cell).get(ele))
{
return cl_base.get(cell).get(ele);
}
//Three next functions are optional
/*! \brief Get an element in the cell
*
* \tparam i property to get
*
* \param cell cell id
* \param ele element id
*
* \return The element value
*
*/
template<unsigned int i> inline auto get(size_t cell, size_t ele) -> decltype(cl_base.get(cell).get(ele))
{
return cl_base.template get<i>(cell)->get(ele);
}
/*! \brief Swap the memory
*
* \param cl Cell list with witch you swap the memory
*
*/
void swap(CellList<dim,T,BALANCED,base> & cl)
{
cl_base.swap(cl.cl_base);
}
/*! \brief Get the Cell iterator
*
* \param return the iterator to the cell
*
*/
CellIterator<CellList<dim,T,BALANCED,base>> getIterator(size_t cell)
{
return CellIterator<CellList<dim,T,BALANCED,base>>(cell,*this);
}
/*! \brief Get the Nearest Neighborhood iterator
*
* \param cell cell id
*
*/
template<unsigned int impl> CellNNIterator<dim,CellList<dim,T,BALANCED,base>,FULL,impl> getNNIterator(size_t cell)
{
CellNNIterator<dim,CellList<dim,T,BALANCED,base>,FULL,impl> cln(cell,NNc_full,*this);
return cln;
}
template<unsigned int impl> CellNNIterator<dim,CellList<dim,T,BALANCED,base>,SYM,impl> getNNIteratorSym(size_t cell)
{
CellNNIterator<dim,CellList<dim,T,BALANCED,base>,SYM,impl> cln(cell,NNc_sym,*this);
return cln;
}
template<unsigned int impl> CellNNIterator<dim,CellList<dim,T,BALANCED,base>,CRS,impl> getNNIteratorCross(size_t cell)
{
CellNNIterator<dim,CellList<dim,T,BALANCED,base>,CRS,impl> cln(cell,NNc_cr,*this);
return cln;
}
};
#endif /* CELLLISTBAL_HPP_ */
......@@ -892,7 +892,7 @@ public:
* \return the iterator to the elements inside cell
*
*/
CellIterator<CellList<dim,T,FAST,transform,base>> getIterator(size_t cell)
CellIterator<CellList<dim,T,FAST,transform,base>> getCellIterator(size_t cell)
{
return CellIterator<CellList<dim,T,FAST,transform,base>>(cell,*this);
}
......
......@@ -5,49 +5,71 @@
* Author: Yaroslav Zaluzhnyi
*/
#ifndef OPENFPM_DATA_SRC_NN_CELLLIST_CELLLISTFAST_HILB_HPP_
#define OPENFPM_DATA_SRC_NN_CELLLIST_CELLLISTFAST_HILB_HPP_
#ifndef OPENFPM_DATA_SRC_NN_CELLLIST_CELLLISTFAST_GEN_HPP_
#define OPENFPM_DATA_SRC_NN_CELLLIST_CELLLISTFAST_GEN_HPP_
#include "CellListFast.hpp"
#include "CellListIterator.hpp"
#define HILBERT 1
#include "CellList.hpp"
extern "C"
{
#include "hilbertKey.h"
}
/* !Brief Class for FAST hilbert cell list implementation
*
* \see CellList<dim,T,FAST,transform,base>
/* !Brief Class for a linear (1D-like) order processing of cell keys for CellList_gen implementation
*
* \tparam dim Dimansionality of the space
* \tparam T type of the space float, double, complex
* \tparam base Base structure that store the information
*
*/
template<unsigned int dim, typename T, unsigned int impl=FAST, typename transform = no_transform<dim,T>, typename base=openfpm::vector<size_t>>
class CellList_hilb : public CellList<dim,T,impl,transform,base>
template<unsigned int dim>
class Process_keys_lin
{
private:
// Ghost marker
size_t g_m = 0;
public:
// vector for storing the cell keys
openfpm::vector<size_t> keys;
/*! \brief Get a linear (1D-like) key from the coordinates and add to the getKeys vector
*
* \tparam S Cell list type
*
* \param obj Cell list object
* \param gk grid key
* \param m order of a curve
*/
template<typename S> static void get_hkey(S & obj, grid_key_dx<dim> gk, size_t m)
{
size_t point[dim];
// vector for storing the particle keys
openfpm::vector<size_t> p_keys;
for (size_t i = 0; i < dim; i++)
{
point[i] = gk.get(i) + obj.getPadding(i);
}
//Order of an hilbert curve
size_t m;
obj.getKeys().add(obj.getGrid().LinIdPtr(static_cast<size_t *>(point)));
}
template<typename S> static void linearize_hkeys(S & obj, size_t m)
{
return;
}
};
/* !Brief Class for an hilbert order processing of cell keys for CellList_gen implementation
*
* \tparam dim Dimansionality of the space
*/
template<unsigned int dim>
class Process_keys_hilb
{
public:
/*! \brief Get an hilbert key from the coordinates and add to the getKeys vector
*
* \param gk grid key
* \tparam S Cell list type
*
* \param obj Cell list object
* \param gk grid key
* \param m order of a curve
*/
void get_hkey(grid_key_dx<dim> gk)
template<typename S> static void get_hkey(S & obj, grid_key_dx<dim> gk, size_t m)
{
//An integer to handle errors
int err;
......@@ -61,15 +83,17 @@ private:
size_t hkey = getHKeyFromIntCoord(m, dim, point, &err);
this->getKeys().add(hkey);
obj.getKeys().add(hkey);
}
/*! \brief Get get the coordinates from hilbert key, linearize and add to the getKeys vector
*
* \tparam S Cell list type
*
*
* \param obj Cell list object
* \param m order of a curve
*/
void linearize_hkeys()
template<typename S> static void linearize_hkeys(S & obj, size_t m)
{
//An integer to handle errors
int err;
......@@ -78,21 +102,67 @@ private:
uint64_t coord[dim];
size_t coord2[dim];
this->getKeys().sort();
obj.getKeys().sort();
openfpm::vector<size_t> keys_new;
for(size_t i = 0; i < this->getKeys().size(); i++)
for(size_t i = 0; i < obj.getKeys().size(); i++)
{
getIntCoordFromHKey(coord, m, dim, this->getKeys().get(i), &err);
getIntCoordFromHKey(coord, m, dim, obj.getKeys().get(i), &err);
for (size_t j = 0 ; j < dim ; j++) {coord2[j] = coord[j] + this->getPadding(j);}
for (size_t j = 0 ; j < dim ; j++) {coord2[j] = coord[j] + obj.getPadding(j);}
keys_new.add(this->getGrid().LinIdPtr(static_cast<size_t *>(coord2)));
keys_new.add(obj.getGrid().LinIdPtr(static_cast<size_t *>(coord2)));
}
this->getKeys().swap(keys_new);
obj.getKeys().swap(keys_new);
}
};
/* \brief Cell list implementation with particle iterator over cells
*
* \see CellList<dim,T,FAST,transform,base>
*
* \tparam dim Dimensionality of the space
* \tparam T type of the space float, double, complex
* \tparam Prock indicate the cell iterator over the Cell
* \tparam Mem_type indicate how the Cell-list are implemented in memory
* \tparam base Base structure that store the information
*
*/
template<unsigned int dim, typename T, typename Prock, typename Mem_type = Mem_fast<dim,T>, typename transform = no_transform<dim,T>, typename base=openfpm::vector<size_t>>
class CellList_gen : public CellList<dim,T,Mem_type,transform,base>, Prock
{
private:
// Ghost marker
// size_t g_m = 0;
/*
// vector for storing the cell keys
openfpm::vector<size_t> keys;
// vector for storing the particle keys
openfpm::vector<size_t> p_keys;
//Order of an hilbert curve
size_t m;*/
/*! \brief Get an hilbert key from the coordinates and add to the getKeys vector
*
* \param gk grid key
*
*/
/* void get_hkey(grid_key_dx<dim> gk)
{
Prock::template get_hkey<CellList_gen<dim,T,Prock,Mem_type,transform,base>>(*this,gk,m);
}*/
/*! \brief Get get the coordinates from hilbert key, linearize and add to the getKeys vector
*
*/
/* void linearize_hkeys()
{
Prock::template linearize_hkeys<CellList_gen<dim,T,Prock,Mem_type,transform,base>>(*this,m);
}*/
public:
......@@ -105,14 +175,15 @@ public:
* \param slot maximum number of slot
*
*/
void Initialize(const Box<dim,T> & box, const size_t (&div)[dim], size_t g_m_new, const size_t pad = 1, size_t slot=STARTING_NSLOT)
/* void Initialize(const Box<dim,T> & box, const size_t (&div)[dim], size_t g_m_new, const size_t pad = 1, size_t slot=STARTING_NSLOT)
{
CellList<dim,T,impl,transform,base>::Initialize(box,div,pad,slot);
CellList<dim,T,Mem_type,transform,base>::Initialize(box,div,pad,slot);
g_m = g_m_new;
size_t sz[dim];
//Get grid_sm without padding (gs_small)
for (size_t i = 0; i < dim ; i++)
sz[i] = this->getGrid().size(i) - 2*pad;
......@@ -126,6 +197,7 @@ public:
a = gs_small.size(i);
}
//Calculate an hilberts curve order
for (m = 0; ; m++)
{
if ((1ul << m) >= a)
......@@ -138,17 +210,18 @@ public:
{
auto gk = it.get();
// Get an hilbert key of each cell and add to 'keys' vector
// Get a key of each cell and add to 'keys' vector
this->get_hkey(gk);
++it;
}
// Sort and linearize hilbert keys
// Sort and linearize keys
this->linearize_hkeys();
}
}*/
CellList_hilb()
:CellList<dim,T,impl,transform,base>(),m(0)
CellList_gen()