OpenFPM  5.2.0
Project that contain the implementation of distributed structures
MonomialBasis.hpp
1 //
2 // Created by tommaso on 20/03/19.
3 //
4 
5 #ifndef OPENFPM_PDATA_MONOMIALBASIS_H
6 #define OPENFPM_PDATA_MONOMIALBASIS_H
7 
8 #include "Vector/map_vector.hpp"
9 #include <Grid/grid_sm.hpp>
10 #include <Grid/iterators/grid_key_dx_iterator_sub_bc.hpp>
11 #include "Monomial.hpp"
12 #include "Monomial.cuh"
13 
14 
15 template<unsigned int dim, typename T = Monomial<dim>, template<typename, template<typename...> class...> class vector_type = openfpm::vector_std, template<typename...> class... Args>
17 {
18 private:
19  vector_type<T, Args...> basis;
20 
21 public:
22  MonomialBasis() {}
23 
24  MonomialBasis(const vector_type<unsigned int, Args...> &degrees, unsigned int convergenceOrder);
25 
26  MonomialBasis(unsigned int orderLimit);
27 
28  MonomialBasis(unsigned int degrees[dim], unsigned int convergenceOrder);
29 
30 // explicit MonomialBasis(Point<dim, unsigned int> degrees, unsigned int convergenceOrder);
31 
32  __host__ __device__ explicit MonomialBasis(const vector_type<T, Args...> &basis) : basis(basis) {}
33 
34  __host__ __device__ MonomialBasis(const MonomialBasis &other);
35 
36  __host__ __device__ MonomialBasis &operator=(const MonomialBasis &other);
37 
38  __host__ __device__ unsigned int size() const;
39 
40  __host__ __device__ const T &getElement(size_t i) const;
41 
42  __host__ __device__ T &getElement(size_t i);
43 
44  __host__ __device__ const vector_type<T, Args...> &getElements() const;
45 
46  __host__ __device__ MonomialBasis<dim, T, vector_type, Args...> getDerivative(Point<dim, unsigned int> differentialOrder) const;
47 
48  __host__ __device__ bool operator==(const MonomialBasis &other) const;
49 
50  __host__ __device__ vector_type<T, Args...>& getBasis() { return basis; }
51 
52  template<typename charT, typename traits>
53  friend std::basic_ostream<charT, traits> &
54  operator<<(std::basic_ostream<charT, traits> &lhs, MonomialBasis<dim, T, vector_type, Args...> const &rhs)
55  {
56  lhs << "MonomialBasis: size=" << rhs.size() << ", elements={ ";
57  for (const auto &el : rhs.getElements())
58  {
59  lhs << "(" << el << ") ";
60  }
61  lhs << "}" << std::endl;
62  return lhs;
63  }
64 
65 
66 
67 private:
68  void generateBasis(vector_type<unsigned int, Args...> m, unsigned int r);
69 };
70 
72 
73 template<unsigned int dim, typename T, template<typename, template<typename...> class...> class vector_type, template<typename...> class... Args>
74 __host__ __device__ MonomialBasis<dim, T, vector_type, Args...>::MonomialBasis(const vector_type<unsigned int, Args...> &degrees, unsigned int convergenceOrder)
75 {
76  generateBasis(degrees, convergenceOrder);
77 }
78 
79 template<unsigned int dim, typename T, template<typename, template<typename...> class...> class vector_type, template<typename...> class... Args>
80 __host__ __device__ MonomialBasis<dim, T, vector_type, Args...>::MonomialBasis(unsigned int *degrees, unsigned int convergenceOrder)
81  : MonomialBasis(vector_type<unsigned int, Args...>(degrees, degrees + dim), convergenceOrder) {}
82 
83 template<unsigned int dim, typename T, template<typename, template<typename...> class...> class vector_type, template<typename...> class... Args>
85 {
86  basis = other.basis; // Here it works because both vector_type and Monomial perform a deep copy.
87 }
88 
89 template<unsigned int dim, typename T, template<typename, template<typename...> class...> class vector_type, template<typename...> class... Args>
90 __host__ __device__ MonomialBasis<dim, T, vector_type, Args...> &MonomialBasis<dim, T, vector_type, Args...>::operator=(const MonomialBasis &other)
91 {
92  basis = other.basis; // Here it works because both vector_type and Monomial perform a deep copy.
93  return *this;
94 }
95 
96 template<unsigned int dim, typename T, template<typename, template<typename...> class...> class vector_type, template<typename...> class... Args>
97 __host__ __device__ unsigned int MonomialBasis<dim, T, vector_type, Args...>::size() const
98 {
99  return basis.size();
100 }
101 
102 template<unsigned int dim, typename T, template<typename, template<typename...> class...> class vector_type, template<typename...> class... Args>
103 __host__ __device__ const T &MonomialBasis<dim, T, vector_type, Args...>::getElement(size_t i) const
104 {
105  return basis.get(i);
106 }
107 
108 template<unsigned int dim, typename T, template<typename, template<typename...> class...> class vector_type, template<typename...> class... Args>
109 __host__ __device__ T &MonomialBasis<dim, T, vector_type, Args...>::getElement(size_t i)
110 {
111  return basis.get(i);
112 }
113 
114 template<unsigned int dim, typename T, template<typename, template<typename...> class...> class vector_type, template<typename...> class... Args>
116 {
117  // Compute the vector of actual dimensions to iterate over
118  // NOTE: each index can go up to sum(m)+r
119  unsigned int mSum = 0U;
120  for (size_t i = 0; i < m.size(); ++i) mSum += m.get(i);
121 
122  unsigned int orderLimit = mSum + r;
123  size_t dimensions[dim];
124  std::fill(dimensions, dimensions + dim, orderLimit);
125 
126  // Now initialize grid with appropriate size, then start-stop points and boundary conditions for the iterator
127  grid_sm<dim, void> grid(dimensions);
128 
129  long int startV[dim] = {}; // 0-initialized
130  grid_key_dx<dim, long int> start(startV);
131  grid_key_dx<dim, long int> stop(dimensions);
132 
133  size_t bc[dim];
134  std::fill(bc, bc + dim, NON_PERIODIC);
135 
136  grid_key_dx_iterator_sub_bc<dim> it(grid, start, stop, bc);
137 
138  // Finally compute alpha_min
139  unsigned char alphaMin = static_cast<unsigned char>(!(mSum % 2)); // if mSum is even, alpha_min must be 1
140  if(mSum==0)
141  {
142  alphaMin = 0;
143  }
144  //std::cout<<"AlphaMin: "<<alphaMin<<std::endl;
145 
146  while (it.isNext())
147  {
148  Point<dim, long int> p = it.get().get_k();
149  T candidateBasisElement(p);
150  // Filter out the elements which don't fullfil the theoretical condition for being in the vandermonde matrix
151  if (candidateBasisElement.order() < orderLimit && candidateBasisElement.order() >= alphaMin)
152  {
153  basis.add(candidateBasisElement);
154  }
155  ++it;
156  }
157 }
158 
159 template<unsigned int dim, typename T, template<typename, template<typename...> class...> class vector_type, template<typename...> class... Args>
160 __host__ __device__ const vector_type<T, Args...> &MonomialBasis<dim, T, vector_type, Args...>::getElements() const
161 {
162  return basis;
163 }
164 
165 template<unsigned int dim, typename T, template<typename, template<typename...> class...> class vector_type, template<typename...> class... Args>
166 __host__ __device__ MonomialBasis<dim, T, vector_type, Args...> MonomialBasis<dim, T, vector_type, Args...>::getDerivative(const Point<dim, unsigned int> differentialOrder) const
167 {
168  vector_type<T, Args...> derivatives;
169 
170  for (size_t i = 0; i < basis.size(); ++i)
171  {
172  // used insted of rhs ref as it does swap internally (not supported by Monomial)
173  T d = basis.get(i).getDerivative(differentialOrder);
174  derivatives.add(d);
175  }
176 
177  return MonomialBasis<dim, T, vector_type, Args...>(derivatives);
178 }
179 
180 template<unsigned int dim, typename T, template<typename, template<typename...> class...> class vector_type, template<typename...> class... Args>
181 __host__ __device__ bool MonomialBasis<dim, T, vector_type, Args...>::operator==(const MonomialBasis &other) const
182 {
183  return basis == other.basis;
184 }
185 
186 //template<unsigned int dim, typename T, template<typename, template<typename...> class...> class vector_type, template<typename...> class... Args>
187 // __host__ __device__ //MonomialBasis<dim, T, vector_type, Args...>::MonomialBasis(Point<dim, unsigned int> degrees, unsigned int convergenceOrder)
188 // : MonomialBasis(degrees.asArray(), convergenceOrder) {}
189 
190 #endif //OPENFPM_PDATA_MONOMIALBASIS_H
The same as grid_key_dx_iterator_sub_p but with periodic boundary.
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:204
Distributed vector.
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data