OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
SupportBuilder.hpp
1 //
2 // Created by tommaso on 25/03/19.
3 //
4 // Modified by Abhinav and Pietro
5 
6 #ifndef OPENFPM_PDATA_SUPPORTBUILDER_HPP
7 #define OPENFPM_PDATA_SUPPORTBUILDER_HPP
8 
9 // This is to automatically get the right support (set of particles) for doing DCPSE on a given particle.
10 // todo: This could be enhanced to support an algorithm for choosing the support in a smart way (to lower condition num)
11 
12 #include <Space/Shape/Point.hpp>
13 #include <Vector/vector_dist.hpp>
14 #include "Support.hpp"
15 #include <utility>
16 
17 enum support_options
18 {
19  N_PARTICLES,
20  RADIUS
21 };
22 
23 template<typename vector_type>
25 {
26 private:
27  vector_type &domain;
28  decltype(std::declval<vector_type>().getCellList(0.0)) cellList;
29  const Point<vector_type::dims, unsigned int> differentialSignature;
30  typename vector_type::stype rCut;
31 
32 public:
33  SupportBuilder(vector_type &domain, Point<vector_type::dims, unsigned int> differentialSignature, typename vector_type::stype rCut);
34 
35  SupportBuilder(vector_type &domain, unsigned int differentialSignature[vector_type::dims], typename vector_type::stype rCut);
36 
37  template<typename iterator_type>
38  Support getSupport(iterator_type itPoint, unsigned int requiredSize, support_options opt)
39  {
40  // Get spatial position from point iterator
41  vect_dist_key_dx p = itPoint.get();
42  vect_dist_key_dx pOrig = itPoint.getOrig();
44 
45  // Get cell containing current point and add it to the set of cell keys
46  grid_key_dx<vector_type::dims> curCellKey = cellList.getCellGrid(pos); // Here get the key of the cell where the current point is
47  std::set<grid_key_dx<vector_type::dims>> supportCells;
48  supportCells.insert(curCellKey);
49 
50  // Make sure to consider a set of cells providing enough points for the support
51  enlargeSetOfCellsUntilSize(supportCells, requiredSize + 1,opt); // NOTE: this +1 is because we then remove the point itself
52 
53  // Now return all the points from the support into a vector
54 
55  std::vector<size_t> supportKeys = getPointsInSetOfCells(supportCells,p,pOrig,requiredSize,opt);
56 
57  auto p_o = domain.getOriginKey(p.getKey());
58  std::remove(supportKeys.begin(), supportKeys.end(), p_o.getKey());
59  return Support(p_o.getKey(), supportKeys);
60  }
61 
62 private:
63  size_t getCellLinId(const grid_key_dx<vector_type::dims> &cellKey);
64 
65  size_t getNumElementsInCell(const grid_key_dx<vector_type::dims> &cellKey);
66 
67  size_t getNumElementsInSetOfCells(const std::set<grid_key_dx<vector_type::dims>> &set);
68 
69  void enlargeSetOfCellsUntilSize(std::set<grid_key_dx<vector_type::dims>> &set, unsigned int requiredSize,support_options opt);
70 
71  std::vector<size_t> getPointsInSetOfCells(std::set<grid_key_dx<vector_type::dims>> set, vect_dist_key_dx & p, vect_dist_key_dx & pOrig, size_t requiredSupportSize, support_options opt);
72 
73  bool isCellKeyInBounds(grid_key_dx<vector_type::dims> key);
74 };
75 
76 // Method definitions below
77 
78 template<typename vector_type>
80  typename vector_type::stype rCut)
81 :domain(domain),
82  differentialSignature(differentialSignature),
83  rCut(rCut)
84 {
85  cellList = domain.getCellList(rCut);
86 }
87 
88 
89 template<typename vector_type>
91 {
92  const size_t curCellId = getCellLinId(cellKey);
93  size_t numElements = cellList.getNelements(curCellId);
94  return numElements;
95 }
96 
97 template<typename vector_type>
99 {
100  size_t tot = 0;
101  for (const auto cell : set)
102  {
103  tot += getNumElementsInCell(cell);
104  }
105  return tot;
106 }
107 
108 template<typename vector_type>
110  support_options opt)
111 {
112  if (opt==support_options::RADIUS){
113  auto cell=*set.begin();
115  int n=std::ceil(rCut/cellList.getCellBox().getHigh(0));
116  size_t sz[vector_type::dims];
117  for (int i=0;i<vector_type::dims;i++)
118  {
119  sz[i]=2*n+1;
120  middle.set_d(i,n);
121  }
124  while(g_k.isNext())
125  {
126  auto key=g_k.get();
127  key=cell+key-middle;
128  if (isCellKeyInBounds(key))
129  {
130  set.insert(key);
131  }
132  ++g_k;
133  }
134  }
135  else{
136  while (getNumElementsInSetOfCells(set) < 5.0*requiredSize) //Why 5*requiredSize? Becasue it can help with adaptive resolutions.
137  {
138  auto tmpSet = set;
139  for (const auto el : tmpSet)
140  {
141  for (unsigned int i = 0; i < vector_type::dims; ++i)
142  {
143  const auto pOneEl = el.move(i, +1);
144  const auto mOneEl = el.move(i, -1);
145  if (isCellKeyInBounds(pOneEl))
146  {
147  set.insert(pOneEl);
148  }
149  if (isCellKeyInBounds(mOneEl))
150  {
151  set.insert(mOneEl);
152  }
153  }
154  }
155 
156  }
157  }
158 }
159 
160 
161 template<typename vector_type>
163 {
164  mem_id id = cellList.getGrid().LinId(cellKey);
165  return static_cast<size_t>(id);
166 }
167 
168 template<typename vector_type>
170  vect_dist_key_dx & p,
171  vect_dist_key_dx & pOrig,
172  size_t requiredSupportSize,
173  support_options opt)
174 {
175  struct reord
176  {
177  typename vector_type::stype dist;
178  size_t offset;
179 
180  bool operator<(const reord & p) const
181  {return this->dist < p.dist;}
182  };
183 
185  std::vector<size_t> points;
187  for (const auto cellKey : set)
188  {
189  const size_t cellLinId = getCellLinId(cellKey);
190  const size_t elemsInCell = getNumElementsInCell(cellKey);
191  for (size_t k = 0; k < elemsInCell; ++k)
192  {
193  size_t el = cellList.get(cellLinId, k);
194 
195  if (pOrig.getKey() == el) {continue;}
196 
198  //points.push_back(el);
199 
200  reord pr;
201 
202  pr.dist = xp.distance(xq);
203  pr.offset = el;
204 
205  rp.add(pr);
206  }
207  }
208 
209  if (opt == support_options::RADIUS)
210  {
211  for (int i = 0 ; i < rp.size() ; i++)
212  {
213  if (rp.get(i).dist < rCut)
214  {
215  points.push_back(rp.get(i).offset);
216  }
217  }
218 /* #ifdef SE_CLASS1
219  if (points.size()<requiredSupportSize)
220  {
221  std::cerr<<__FILE__<<":"<<__LINE__<<"Note that the DCPSE neighbourhood doesn't have asked no. particles (Increase the rCut or reduce the over_sampling factor)";
222  std::cout<<"Particels asked (minimum*oversampling_factor): "<<requiredSupportSize<<". Particles Possible with given options:"<<points.size()<<"."<<std::endl;
223  }
224  #endif*/
225  }
226  else
227  { rp.sort();
228  for (int i = 0 ; i < requiredSupportSize ; i++)
229  {
230  points.push_back(rp.get(i).offset);
231  }
232  }
233 
234  return points;
235 }
236 
237 template<typename vector_type>
238 SupportBuilder<vector_type>::SupportBuilder(vector_type &domain, unsigned int *differentialSignature, typename vector_type::stype rCut)
239  : SupportBuilder(domain, Point<vector_type::dims, unsigned int>(differentialSignature), rCut) {}
240 
241 template<typename vector_type>
243 {
244  const size_t *cellGridSize = cellList.getGrid().getSize();
245  for (size_t i = 0; i < vector_type::dims; ++i)
246  {
247  if (key.value(i) < 0 || key.value(i) >= cellGridSize[i])
248  {
249  return false;
250  }
251  }
252  return true;
253 }
254 
255 #endif //OPENFPM_PDATA_SUPPORTBUILDER_HPP
auto getPosOrig(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:18
St stype
space type
auto getPos(vect_dist_key_dx vec_key) -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
Grid key for a distributed grid.
size_t size()
Stub size.
Definition: map_vector.hpp:211
CellL getCellList(St r_cut, bool no_se3=false)
Construct a cell list starting from the stored particles.
__device__ __host__ mem_id value(size_t i) const
Get the i index.
Definition: grid_key.hpp:477
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
static const unsigned int dims
dimensions of space
__device__ __host__ size_t getKey() const
Get the key.
Declaration grid_sm.
Definition: grid_sm.hpp:147
__device__ __host__ T distance(const Point< dim, T > &q) const
It calculate the distance between 2 points.
Definition: Point.hpp:250
Distributed vector.
__device__ __host__ void set_d(index_type i, index_type id)
Set the i index.
Definition: grid_key.hpp:516
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:202