OpenFPM  5.2.0
Project that contain the implementation of distributed structures
Vandermonde.hpp
1 //
2 // Created by tommaso on 21/03/19.
3 // Edited by Abhinav Singh on 24/01/2022
4 
5 #ifndef OPENFPM_PDATA_VANDERMONDE_HPP
6 #define OPENFPM_PDATA_VANDERMONDE_HPP
7 
8 #include "MonomialBasis.hpp"
9 #include "VandermondeRowBuilder.hpp"
10 
11 template<unsigned int dim, typename T, typename MatrixType>
13 {
14 private:
15  const Point<dim, T> point;
17  const MonomialBasis<dim> monomialBasis;
18  T eps,HOverEpsilon,minSpacing;
19 
20 public:
21  template<typename verletIterator_type, typename vector_type, typename vector_type2>
23  size_t p,
24  verletIterator_type &it,
25  const MonomialBasis<dim> &monomialBasis,
26  const vector_type & particlesSupport,
27  const vector_type2 & particlesDomain,T HOverEpsilon=0.5
28  ):
29  monomialBasis(monomialBasis),
30  HOverEpsilon(HOverEpsilon)
31  {
32  initialize(p, it, particlesSupport, particlesDomain);
33  }
34 
35 
36  MatrixType &getMatrix(MatrixType &V)
37  {
38  // Build the Vandermonde matrix, row-by-row
39  VandermondeRowBuilder<dim, T> vrb(monomialBasis);
40  unsigned int row = 0;
41 
42  size_t N = x_pqVec.size();
43  for (unsigned int row = 0; row < N; ++row)
44  {
45  const auto& x_pq = x_pqVec.get(row);
46  vrb.buildRow(V, row, x_pq / eps);
47  }
48  return V;
49  }
50 
51  T getEps()
52  {
53  return eps;
54  }
55  T getMinSpacing()
56  {
57  return minSpacing;
58  }
59 
60 private:
61 
62 
63  void computeEps(T factor)
64  {
65  T avgNeighbourSpacing = 0;
66  minSpacing=std::numeric_limits<T>::max();
67  size_t N = x_pqVec.size();
68  for (size_t i = 0; i < N; ++i)
69  {
70  const auto& x_pq = x_pqVec.get(i);
71  T dist=norm(x_pq);
72  avgNeighbourSpacing += computeAbsSum(x_pq);
73  if(minSpacing>dist)
74  {
75  minSpacing=dist;
76  }
77  }
78  avgNeighbourSpacing /= x_pqVec.size();
79  eps = avgNeighbourSpacing/factor;
80  assert(eps != 0);
81  }
82 
83  static T computeAbsSum(const Point<dim, T> &x)
84  {
85  T absSum = 0;
86  for (unsigned int i = 0; i < dim; ++i)
87  {
88  absSum += fabs(x.value(i));
89  }
90  return absSum;
91  }
92 
93  template<typename verletIterator_type, typename vector_type, typename vector_type2>
94  void initialize(size_t p, verletIterator_type &it, const vector_type & particlesSupport, vector_type2 &particlesDomain)
95  {
96  while (it.isNext())
97  {
98  size_t q = it.get();
99 
100  Point<dim,T> xp = particlesDomain.getPos(p);
101  xp -= particlesSupport.getPos(q);
102  x_pqVec.add(xp);
103 
104  ++it;
105  }
106 
107 
108  // First check that the number of points given is enough for building the Vandermonde matrix
109  if (x_pqVec.size() < monomialBasis.size())
110  {
111  ACTION_ON_ERROR(std::length_error("Not enough neighbour points passed for Vandermonde matrix construction!"));
112  }
113  // Compute eps for this point
114  // factor here. This is C factor.
115  computeEps(HOverEpsilon);
116  }
117 
118 };
119 
120 
121 
122 #endif //OPENFPM_PDATA_VANDERMONDE_HPP
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:28
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:204
size_t size()
Stub size.
Definition: map_vector.hpp:212
auto getPos(size_t vec_key) -> decltype(vd.getPos(vec_key))
Get the position of an element.
Distributed vector.
auto getPos(vect_dist_key_dx vec_key) -> decltype(vPos.template get< 0 >(vec_key.getKey()))
Get the position of an element.