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