OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
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
17enum support_options
18{
19 N_PARTICLES,
20 RADIUS,
21 LOAD,
22 ADAPTIVE
23};
24
25
26template<typename vector_type,typename vector_type2>
28private:
29 vector_type &domainFrom;
30 vector_type2 &domainTo;
31 decltype(std::declval<vector_type>().getCellList(0.0)) cellList;
32 const Point<vector_type::dims, unsigned int> differentialSignature;
33 typename vector_type::stype rCut, MinSpacing, AdapFac=1;
34 bool is_interpolation;
35
36public:
37
38 SupportBuilder(vector_type &domainFrom, vector_type2 &domainTo,
39 const Point<vector_type::dims, unsigned int> differentialSignature,
40 typename vector_type::stype rCut,
41 bool is_interpolation)
42 : domainFrom(domainFrom),
43 domainTo(domainTo),
44 differentialSignature(differentialSignature),
45 rCut(rCut), is_interpolation(is_interpolation) {
46 cellList = domainFrom.getCellList(rCut);
47 }
48
49 SupportBuilder(vector_type &domainFrom, vector_type2 &domainTo,
50 unsigned int differentialSignature[vector_type::dims], typename vector_type::stype rCut,
51 bool is_interpolation)
52 : SupportBuilder(domainFrom, domainTo, Point<vector_type::dims, unsigned int>(differentialSignature),
53 rCut) {}
54
55 template<typename iterator_type>
56 Support getSupport(iterator_type itPoint, unsigned int requiredSize, support_options opt) {
57 // Get spatial position from point iterator
58 vect_dist_key_dx p = itPoint.get();
59 vect_dist_key_dx pOrig = itPoint.getOrig();
61
62 // Get cell containing current point and add it to the set of cell keys
63 grid_key_dx<vector_type::dims> curCellKey = cellList.getCellGrid(
64 pos); // Here get the key of the cell where the current point is
65 std::set<grid_key_dx<vector_type::dims>> supportCells;
66 supportCells.insert(curCellKey);
67
68 // Make sure to consider a set of cells providing enough points for the support
69 enlargeSetOfCellsUntilSize(supportCells, requiredSize + 1,
70 opt); // NOTE: this +1 is because we then remove the point itself
71
72 // Now return all the points from the support into a vector
73
74 std::vector<size_t> supportKeys = getPointsInSetOfCells(supportCells, p, pOrig, requiredSize, opt);
75
76 if (is_interpolation == false) {
77 auto p_o = domainFrom.getOriginKey(p.getKey());
78 std::remove(supportKeys.begin(), supportKeys.end(), p_o.getKey());
79 }
80
81 auto p_o = domainTo.getOriginKey(p.getKey());
82 return Support(p_o.getKey(), openfpm::vector_std<size_t>(supportKeys.begin(), supportKeys.end()));
83 }
84
85 typename vector_type::stype getLastMinspacing() {
86 return this->MinSpacing;
87 }
88
89 void setAdapFac(typename vector_type::stype fac) {
90 this->AdapFac=fac;
91 }
92
93private:
94
95 size_t getCellLinId(const grid_key_dx<vector_type::dims> &cellKey) {
96 mem_id id = cellList.getGrid().LinId(cellKey);
97 return static_cast<size_t>(id);
98 }
99
100 size_t getNumElementsInCell(const grid_key_dx<vector_type::dims> &cellKey) {
101 const size_t curCellId = getCellLinId(cellKey);
102 size_t numElements = cellList.getNelements(curCellId);
103 return numElements;
104 }
105
106 size_t getNumElementsInSetOfCells(const std::set<grid_key_dx<vector_type::dims>> &set) {
107 size_t tot = 0;
108 for (const auto cell: set) {
109 tot += getNumElementsInCell(cell);
110 }
111 return tot;
112 }
113
114 void enlargeSetOfCellsUntilSize(std::set<grid_key_dx<vector_type::dims>> &set, unsigned int requiredSize,
115 support_options opt) {
116 if (opt == support_options::RADIUS || opt == support_options::ADAPTIVE) {
117 auto cell = *set.begin();
119 int n = std::ceil(rCut / cellList.getCellBox().getHigh(0));
120 size_t sz[vector_type::dims];
121 for (int i = 0; i < vector_type::dims; i++) {
122 sz[i] = 2 * n + 1;
123 middle.set_d(i, n);
124 }
127 while (g_k.isNext()) {
128 auto key = g_k.get();
129 key = cell + key - middle;
130 if (isCellKeyInBounds(key)) {
131 set.insert(key);
132 }
133 ++g_k;
134 }
135 } else {
136 while (getNumElementsInSetOfCells(set) <
137 5.0 * requiredSize) //Why 5*requiredSize? Becasue it can help with adaptive resolutions.
138 {
139 auto tmpSet = set;
140 for (const auto el: tmpSet) {
141 for (unsigned int i = 0; i < vector_type::dims; ++i) {
142 const auto pOneEl = el.move(i, +1);
143 const auto mOneEl = el.move(i, -1);
144 if (isCellKeyInBounds(pOneEl)) {
145 set.insert(pOneEl);
146 }
147 if (isCellKeyInBounds(mOneEl)) {
148 set.insert(mOneEl);
149 }
150 }
151 }
152
153 }
154 }
155 }
156
157 std::vector<size_t> getPointsInSetOfCells(std::set<grid_key_dx<vector_type::dims>> set,
159 vect_dist_key_dx &pOrig,
160 size_t requiredSupportSize,
161 support_options opt) {
162 struct reord {
163 typename vector_type::stype dist;
164 size_t offset;
165
166 bool operator<(const reord &p) const { return this->dist < p.dist; }
167 };
168
170 std::vector<size_t> points;
172 for (const auto cellKey: set) {
173 const size_t cellLinId = getCellLinId(cellKey);
174 const size_t elemsInCell = getNumElementsInCell(cellKey);
175 for (size_t k = 0; k < elemsInCell; ++k) {
176 size_t el = cellList.get(cellLinId, k);
177
178 if (pOrig.getKey() == el && is_interpolation == false) { continue; }
179
181 //points.push_back(el);
182
183 reord pr;
184
185 pr.dist = xp.distance(xq);
186 pr.offset = el;
187 rp.add(pr);
188 }
189 }
190
191 if (opt == support_options::RADIUS) {
192 for (int i = 0; i < rp.size(); i++) {
193 if (rp.get(i).dist < rCut) {
194 points.push_back(rp.get(i).offset);
195 }
196 }
197 /* #ifdef SE_CLASS1
198 if (points.size()<requiredSupportSize)
199 {
200 std::cerr<<__FILE__<<":"<<__LINE__<<"Note that the DCPSE neighbourhood doesn't have asked no. particles (Increase the rCut or reduce the over_sampling factor)";
201 std::cout<<"Particels asked (minimum*oversampling_factor): "<<requiredSupportSize<<". Particles Possible with given options:"<<points.size()<<"."<<std::endl;
202 }
203 #endif*/
204 }
205 else if(opt == support_options::ADAPTIVE) {
206 MinSpacing = std::numeric_limits<double>::max();
207 for (int i = 0; i < rp.size(); i++) {
208 if (MinSpacing > rp.get(i).dist && rp.get(i).dist != 0) {
209 MinSpacing = rp.get(i).dist;
210 }
211 }
212#ifdef SE_CLASS1
213 assert(MinSpacing !=0 && "You have multiple particles on the same position.");
214#endif
215 for (int i = 0; i < rp.size(); i++) {
216 if (rp.get(i).dist < AdapFac * MinSpacing) {
217 points.push_back(rp.get(i).offset);
218 }
219 }
220 }
221 else {
222 rp.sort();
223 for (int i = 0; i < requiredSupportSize; i++) {
224 points.push_back(rp.get(i).offset);
225 }
226 }
227
228 //MinSpacing=MinSpacing/requiredSupportSize
229 return points;
230 }
231
232 bool isCellKeyInBounds(grid_key_dx<vector_type::dims> key)
233 {
234 const size_t *cellGridSize = cellList.getGrid().getSize();
235 for (size_t i = 0; i < vector_type::dims; ++i)
236 {
237 if (key.value(i) < 0 || key.value(i) >= cellGridSize[i])
238 {
239 return false;
240 }
241 }
242 return true;
243 }
244};
245
246
247#endif //OPENFPM_PDATA_SUPPORTBUILDER_HPP
This class implement the point shape in an N-dimensional space.
Definition Point.hpp:28
__device__ __host__ T distance(const Point< dim, T > &q) const
It calculate the distance between 2 points.
Definition Point.hpp:250
const grid_key_dx< dim > & get() const
Get the actual key.
bool isNext()
Check if there is the next element.
grid_key_dx is the key to access any element in the grid
Definition grid_key.hpp:19
__device__ __host__ mem_id value(size_t i) const
Get the i index.
Definition grid_key.hpp:477
__device__ __host__ void set_d(index_type i, index_type id)
Set the i index.
Definition grid_key.hpp:516
Declaration grid_sm.
Definition grid_sm.hpp:167
Implementation of 1-D std::vector like structure.
size_t size()
Stub size.
Grid key for a distributed grid.
__device__ __host__ size_t getKey() const
Get the key.
auto getPos(vect_dist_key_dx vec_key) -> decltype(vd.getPos(vec_key))
Get the position of an element.
Distributed vector.
static const unsigned int dims
template parameters typedefs
CellL getCellList(St r_cut, bool no_se3=false)
Construct a cell list starting from the stored particles.
auto getPosOrig(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.