Loading...
Searching...
No Matches
reconstruction.hpp
1/*---------------------------------------------------------------------------*\
2 *
3 * bitpit
4 *
5 * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6 *
7 * -------------------------------------------------------------------------
8 * License
9 * This file is part of bitpit.
10 *
11 * bitpit is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License v3 (LGPL)
13 * as published by the Free Software Foundation.
14 *
15 * bitpit is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with bitpit. If not, see <http://www.gnu.org/licenses/>.
22 *
23\*---------------------------------------------------------------------------*/
24
25#ifndef __BTPIT_RECONSTRUCTION_HPP__
26#define __BTPIT_RECONSTRUCTION_HPP__
27
28#include <array>
29#include <iostream>
30#include <memory>
31#include <vector>
32
33#include "bitpit_patchkernel.hpp"
34
35namespace bitpit {
36
38
39friend class ReconstructionKernel;
40friend class ReconstructionAssembler;
41
42public:
44 ReconstructionPolynomial(uint8_t degree, uint8_t dimensions, const std::array<double, 3> &origin, int nFields=1);
45
50
51 void swap(ReconstructionPolynomial &other) noexcept;
52
53 void initialize(uint8_t degree, uint8_t dimensions, const std::array<double, 3> &origin, int nFields=1, bool release = true);
54 void clear(bool release = true);
55
56 uint8_t getDegree() const;
57 uint8_t getDimensions() const;
58 const std::array<double, 3> & getOrigin() const;
59
60 uint16_t getCoefficientCount() const;
61
62 int getFieldCount() const;
63
64 const double * getCoefficients() const;
65 double * getCoefficients();
66 const double * getCoefficients(int field) const;
67 double * getCoefficients(int field);
68 const double * getDegreeCoefficients(uint8_t degree, int field = 0) const;
69 double * getDegreeCoefficients(uint8_t degree, int field = 0);
70
71 void computeValue(const std::array<double, 3> &point, int field, double *values) const;
72 void computeValues(const std::array<double, 3> &point, double *values) const;
73 void computeValues(const std::array<double, 3> &point, int nFields, double *values) const;
74 void computeValues(const std::array<double, 3> &point, int nFields, int offset, double *values) const;
75 void computeValue(int degree, const std::array<double, 3> &point, int field, double *values) const;
76 void computeValues(int degree, const std::array<double, 3> &point, double *values) const;
77 void computeValues(int degree, const std::array<double, 3> &point, int nFields, double *values) const;
78 void computeValues(int degree, const std::array<double, 3> &point, int nFields, int offset, double *values) const;
79
80 void computeValueLimited(const std::array<double, 3> &point, const double *limiters, int field, double *value) const;
81 void computeValuesLimited(const std::array<double, 3> &point, const double *limiters, double *values) const;
82 void computeValuesLimited(const std::array<double, 3> &point, const double *limiters, int nFields, double *values) const;
83 void computeValuesLimited(const std::array<double, 3> &point, const double *limiters, int nFields, int offset, double *values) const;
84 void computeValueLimited(int degree, const std::array<double, 3> &point, const double *limiters, int field, double *values) const;
85 void computeValuesLimited(int degree, const std::array<double, 3> &point, const double *limiters, double *values) const;
86 void computeValuesLimited(int degree, const std::array<double, 3> &point, const double *limiters, int nFields, double *values) const;
87 void computeValuesLimited(int degree, const std::array<double, 3> &point, const double *limiters, int nFields, int offset, double *values) const;
88
89 void computeDerivative(const std::array<double, 3> &point, const std::array<double, 3> &direction, int field, double *derivative) const;
90 void computeDerivatives(const std::array<double, 3> &point, const std::array<double, 3> &direction, double *derivatives) const;
91 void computeDerivatives(const std::array<double, 3> &point, const std::array<double, 3> &direction, int nFields, double *derivatives) const;
92 void computeDerivatives(const std::array<double, 3> &point, const std::array<double, 3> &direction, int nFields, int offset, double *derivatives) const;
93 void computeDerivative(int degree, const std::array<double, 3> &point, const std::array<double, 3> &direction, int field, double *derivative) const;
94 void computeDerivatives(int degree, const std::array<double, 3> &point, const std::array<double, 3> &direction, double *derivatives) const;
95 void computeDerivatives(int degree, const std::array<double, 3> &point, const std::array<double, 3> &direction, int nFields, double *derivatives) const;
96 void computeDerivatives(int degree, const std::array<double, 3> &point, const std::array<double, 3> &direction, int nFields, int offset, double *derivatives) const;
97
98 void computeDerivativeLimited(const std::array<double, 3> &point, const std::array<double, 3> &direction, const double *limiters, int field, double *derivative) const;
99 void computeDerivativesLimited(const std::array<double, 3> &point, const std::array<double, 3> &direction, const double *limiters, double *derivatives) const;
100 void computeDerivativesLimited(const std::array<double, 3> &point, const std::array<double, 3> &direction, const double *limiters, int nFields, double *derivatives) const;
101 void computeDerivativesLimited(const std::array<double, 3> &point, const std::array<double, 3> &direction, const double *limiters, int nFields, int offset, double *derivatives) const;
102 void computeDerivativeLimited(int degree, const std::array<double, 3> &point, const std::array<double, 3> &direction, const double *limiters, int field, double *derivative) const;
103 void computeDerivativesLimited(int degree, const std::array<double, 3> &point, const std::array<double, 3> &direction, const double *limiters, double *derivatives) const;
104 void computeDerivativesLimited(int degree, const std::array<double, 3> &point, const std::array<double, 3> &direction, const double *limiters, int nFields, double *derivatives) const;
105 void computeDerivativesLimited(int degree, const std::array<double, 3> &point, const std::array<double, 3> &direction, const double *limiters, int nFields, int offset, double *derivatives) const;
106
107 void computeGradient(const std::array<double, 3> &point, int field, std::array<double, 3> *gradient) const;
108 void computeGradients(const std::array<double, 3> &point, std::array<double, 3> *gradients) const;
109 void computeGradients(const std::array<double, 3> &point, int nFields, std::array<double, 3> *gradients) const;
110 void computeGradients(const std::array<double, 3> &point, int nFields, int offset, std::array<double, 3> *gradients) const;
111 void computeGradient(int degree, const std::array<double, 3> &point, int field, std::array<double, 3> *gradient) const;
112 void computeGradients(int degree, const std::array<double, 3> &point, std::array<double, 3> *gradients) const;
113 void computeGradients(int degree, const std::array<double, 3> &point, int nFields, std::array<double, 3> *gradients) const;
114 void computeGradients(int degree, const std::array<double, 3> &point, int nFields, int offset, std::array<double, 3> *gradients) const;
115
116 void computeGradientLimited(const std::array<double, 3> &point, const double *limiters, int field, std::array<double, 3> *gradient) const;
117 void computeGradientsLimited(const std::array<double, 3> &point, const double *limiters, std::array<double, 3> *gradients) const;
118 void computeGradientsLimited(const std::array<double, 3> &point, const double *limiters, int nFields, std::array<double, 3> *gradients) const;
119 void computeGradientsLimited(const std::array<double, 3> &point, const double *limiters, int nFields, int offset, std::array<double, 3> *gradients) const;
120 void computeGradientLimited(int degree, const std::array<double, 3> &point, const double *limiters, int field, std::array<double, 3> *gradient) const;
121 void computeGradientsLimited(int degree, const std::array<double, 3> &point, const double *limiters, std::array<double, 3> *gradients) const;
122 void computeGradientsLimited(int degree, const std::array<double, 3> &point, const double *limiters, int nFields, std::array<double, 3> *gradients) const;
123 void computeGradientsLimited(int degree, const std::array<double, 3> &point, const double *limiters, int nFields, int offset, std::array<double, 3> *gradients) const;
124
125 void display(std::ostream &out) const;
126
127protected:
128 static const uint8_t MAX_DEGREE;
129 static const uint8_t MAX_DIMENSIONS;
130
131 static uint16_t getCoefficientCount(uint8_t degree, uint8_t dimensions);
132 static const std::vector<uint16_t> & getCoefficientsCount(uint8_t dimensions);
133 static uint16_t countCoefficients(uint8_t degree, uint8_t dimensions);
134 static const std::vector<uint16_t> & getDegreeCoefficientsCount(uint8_t dimensions);
135
136 static uint16_t getDegreeCoefficientCount(uint8_t degree, uint8_t dimensions);
137 static uint16_t countDegreeCoefficients(uint8_t degree, uint8_t dimensions);
138
139 static void evalPointBasisValues(uint8_t degree, uint8_t dimensions, const std::array<double, 3> &origin, const std::array<double, 3> &point, double *csi);
140 static void evalPointBasisDerivatives(uint8_t degree, uint8_t dimensions, const std::array<double, 3> &origin, const std::array<double, 3> &point, const std::array<double, 3> &direction, double *dcsi);
141
142 static void evalCellBasisValues(uint8_t degree, uint8_t dimensions, const std::array<double, 3> &origin, const Cell &cell, const std::array<double, 3> *vertexCoords, double *csi);
143
144private:
145 static const bool ENABLE_FAST_PATH_OPTIMIZATIONS;
146 static const int MAX_STACK_WORKSPACE_SIZE;
147
148 const static std::vector<std::vector<uint16_t>> m_countCoefficientCache;
149 const static std::vector<std::vector<uint16_t>> m_countDegreeCoefficientCache;
150
151 static std::vector<std::vector<uint16_t>> generateCountCoefficientCache();
152 static std::vector<std::vector<uint16_t>> generateCountDegreeCoefficientCache();
153
154 uint8_t m_degree;
155 uint8_t m_dimensions;
156
157 int m_nFields;
158
159 uint16_t m_nCoeffs;
160 std::unique_ptr<double[]> m_coeffs;
161
162 std::array<double, 3> m_origin;
163
164 std::size_t computeFieldCoefficientsOffset(uint8_t degree, int field) const;
165 std::size_t getFieldCoefficientsStride() const;
166
167};
168
170
171public:
173 ReconstructionKernel(uint8_t degree, uint8_t dimensions, int nEquations);
174
179
180 void swap(ReconstructionKernel &other) noexcept;
181
182 void initialize(uint8_t degree, uint8_t dimensions, int nEquations, bool release = true);
183
184 uint8_t getDegree() const;
185 uint8_t getDimensions() const;
186
187 uint16_t getCoefficientCount() const;
188
189 int getEquationCount() const;
190
191 const double * getPolynomialWeights() const;
192 double * getPolynomialWeights();
193
194 void assemblePolynomial(const std::array<double, 3> &origin, const double *values, ReconstructionPolynomial *polynomial) const;
195 void assemblePolynomial(const std::array<double, 3> &origin, int nFields, const double **values, ReconstructionPolynomial *polynomial) const;
196 void assemblePolynomial(uint8_t degree, const std::array<double, 3> &origin, const double *values, ReconstructionPolynomial *polynomial) const;
197 void assemblePolynomial(uint8_t degree, const std::array<double, 3> &origin, int nFields, const double **values, ReconstructionPolynomial *polynomial) const;
198
199 void updatePolynomial(const double *values, ReconstructionPolynomial *polynomial) const;
200 void updatePolynomial(int nFields, const double **values, ReconstructionPolynomial *polynomial) const;
201 void updatePolynomial(uint8_t degree, const double *values, ReconstructionPolynomial *polynomial) const;
202 void updatePolynomial(uint8_t degree, int nFields, const double **values, ReconstructionPolynomial *polynomial) const;
203
204 void computeValueWeights(const std::array<double, 3> &origin, const std::array<double, 3> &point, double *valueWeights) const;
205 void computeValueWeights(uint8_t degree, const std::array<double, 3> &origin, const std::array<double, 3> &point, double *valueWeights) const;
206 void computeValueWeights(int nEquations, uint8_t degree, const std::array<double, 3> &origin, const std::array<double, 3> &point, double *valueWeights) const;
207 void computeValueLimitedWeights(const std::array<double, 3> &origin, const std::array<double, 3> &point, const double *limiters, double *valueWeights) const;
208 void computeValueLimitedWeights(uint8_t degree, const std::array<double, 3> &origin, const std::array<double, 3> &point, const double *limiters, double *valueWeights) const;
209 void computeValueLimitedWeights(int nEquations, uint8_t degree, const std::array<double, 3> &origin, const std::array<double, 3> &point, const double *limiters, double *valueWeights) const;
210
211 void computeDerivativeWeights(const std::array<double, 3> &origin, const std::array<double, 3> &point, const std::array<double, 3> &direction, double *derivativeWeights) const;
212 void computeDerivativeWeights(uint8_t degree, const std::array<double, 3> &origin, const std::array<double, 3> &point, const std::array<double, 3> &direction, double *derivativeWeights) const;
213 void computeDerivativeWeights(int nEquations, uint8_t degree, const std::array<double, 3> &origin, const std::array<double, 3> &point, const std::array<double, 3> &direction, double *derivativeWeights) const;
214 void computeDerivativeLimitedWeights(const std::array<double, 3> &origin, const std::array<double, 3> &point, const std::array<double, 3> &direction, const double *limiters, double *derivativeWeights) const;
215 void computeDerivativeLimitedWeights(uint8_t degree, const std::array<double, 3> &origin, const std::array<double, 3> &point, const std::array<double, 3> &direction, const double *limiters, double *derivativeWeights) const;
216 void computeDerivativeLimitedWeights(int nEquations, uint8_t degree, const std::array<double, 3> &origin, const std::array<double, 3> &point, const std::array<double, 3> &direction, const double *limiters, double *derivativeWeights) const;
217
218 void computeGradientWeights(const std::array<double, 3> &origin, const std::array<double, 3> &point, std::array<double, 3> *gradientWeights) const;
219 void computeGradientWeights(uint8_t degree, const std::array<double, 3> &origin, const std::array<double, 3> &point, std::array<double, 3> *gradientWeights) const;
220 void computeGradientWeights(int nEquations, uint8_t degree, const std::array<double, 3> &origin, const std::array<double, 3> &point, std::array<double, 3> *gradientWeights) const;
221 void computeGradientLimitedWeights(const std::array<double, 3> &origin, const std::array<double, 3> &point, const double *limiters, std::array<double, 3> *gradientWeights) const;
222 void computeGradientLimitedWeights(uint8_t degree, const std::array<double, 3> &origin, const std::array<double, 3> &point, const double *limiters, std::array<double, 3> *gradientWeights) const;
223 void computeGradientLimitedWeights(int nEquations, uint8_t degree, const std::array<double, 3> &origin, const std::array<double, 3> &point, const double *limiters, std::array<double, 3> *gradientWeights) const;
224
225 void display(std::ostream &out, double tolerance = 1.e-10) const;
226
227protected:
228 void applyLimiter(uint8_t degree, const double *limiters, double *coeffs) const;
229
230private:
231 static const bool ENABLE_FAST_PATH_OPTIMIZATIONS;
232 static const int MAX_STACK_WORKSPACE_SIZE;
233
234 std::unique_ptr<double[]> m_weights;
235
236 int m_nEquations;
237
238 uint16_t m_nCoeffs;
239
240 uint8_t m_degree;
241 uint8_t m_dimensions;
242
243};
244
246
247public:
248 enum ReconstructionType {
249 TYPE_CONSTRAINT,
250 TYPE_LEAST_SQUARE
251 };
252
254 ReconstructionAssembler(uint8_t degree, uint8_t dimensions);
255
256 void swap(ReconstructionAssembler &other) noexcept;
257
258 void initialize(uint8_t degree, uint8_t dimensions, bool release = true);
259 void clear(bool release = true);
260
261 uint8_t getDegree() const;
262 uint8_t getDimensions() const;
263
264 uint16_t getCoefficientCount() const;
265
266 int countConstraints() const;
267 int countLeastSquares() const;
268 int countEquations() const;
269
270 void addPointValueEquation(ReconstructionType type, const std::array<double, 3> &origin, const std::array<double, 3> &point, double scaleFactor = 1.);
271 void addPointDerivativeEquation(ReconstructionType type, const std::array<double, 3> &origin, const std::array<double, 3> &point, const std::array<double, 3> &direction, double scaleFactor = 1.);
272 void addCellAverageEquation(ReconstructionType type, const Cell &cell, const std::array<double, 3> &origin, const std::array<double, 3> *vertexCoords, double scaleFactor = 1.);
273
274 void assembleKernel(ReconstructionKernel *kernel) const;
275
276 void updateKernel(ReconstructionKernel *kernel) const;
277
278private:
279 static const double SVD_ZERO_THRESHOLD;
280
281 uint8_t m_degree;
282 uint8_t m_dimensions;
283
284 uint16_t m_nCoeffs;
285
286 std::vector<int> m_constraintsOrder;
287 std::vector<int> m_leastSquaresOrder;
288
289 std::vector<double> m_leastSquaresScaleFactors;
290
291 std::vector<double> m_A;
292 std::vector<double> m_C;
293
294 mutable std::vector<double> m_sigma;
295 mutable std::vector<double> m_U;
296 mutable std::vector<double> m_S;
297 mutable std::vector<double> m_Vt;
298 mutable std::vector<double> m_SVDWorkspace;
299 mutable std::vector<double> m_w;
300
301 double * _addEquation(ReconstructionType type, double scaleFactor);
302
303 void computePseudoInverse(int m, int n, double tolerance, double *A) const;
304
305};
306
308
309public:
310 Reconstruction(uint8_t degree, uint8_t dimensions);
311
312 void swap(Reconstruction &other) noexcept;
313
314 void initialize(uint8_t degree, uint8_t dimensions, bool release = true);
315 void clear(bool release = true);
316
319
321
322 void assemble();
323
324};
325
326}
327
328#endif
The Cell class defines the cells.
Definition cell.hpp:42
The ReconstructionAssembler class allows to define reconstruction polynomial.
void swap(ReconstructionAssembler &other) noexcept
void addPointValueEquation(ReconstructionType type, const std::array< double, 3 > &origin, const std::array< double, 3 > &point, double scaleFactor=1.)
void assembleKernel(ReconstructionKernel *kernel) const
void initialize(uint8_t degree, uint8_t dimensions, bool release=true)
void addPointDerivativeEquation(ReconstructionType type, const std::array< double, 3 > &origin, const std::array< double, 3 > &point, const std::array< double, 3 > &direction, double scaleFactor=1.)
void addCellAverageEquation(ReconstructionType type, const Cell &cell, const std::array< double, 3 > &origin, const std::array< double, 3 > *vertexCoords, double scaleFactor=1.)
void updateKernel(ReconstructionKernel *kernel) const
The ReconstructionKernel class allows to evaluate the weight of a reconstruction polynomial previousl...
void computeGradientWeights(const std::array< double, 3 > &origin, const std::array< double, 3 > &point, std::array< double, 3 > *gradientWeights) const
void computeValueWeights(const std::array< double, 3 > &origin, const std::array< double, 3 > &point, double *valueWeights) const
void computeGradientLimitedWeights(const std::array< double, 3 > &origin, const std::array< double, 3 > &point, const double *limiters, std::array< double, 3 > *gradientWeights) const
void updatePolynomial(const double *values, ReconstructionPolynomial *polynomial) const
void computeDerivativeLimitedWeights(const std::array< double, 3 > &origin, const std::array< double, 3 > &point, const std::array< double, 3 > &direction, const double *limiters, double *derivativeWeights) const
void swap(ReconstructionKernel &other) noexcept
void initialize(uint8_t degree, uint8_t dimensions, int nEquations, bool release=true)
void display(std::ostream &out, double tolerance=1.e-10) const
void computeValueLimitedWeights(const std::array< double, 3 > &origin, const std::array< double, 3 > &point, const double *limiters, double *valueWeights) const
void computeDerivativeWeights(const std::array< double, 3 > &origin, const std::array< double, 3 > &point, const std::array< double, 3 > &direction, double *derivativeWeights) const
ReconstructionKernel & operator=(const ReconstructionKernel &other)
void assemblePolynomial(const std::array< double, 3 > &origin, const double *values, ReconstructionPolynomial *polynomial) const
const double * getPolynomialWeights() const
void applyLimiter(uint8_t degree, const double *limiters, double *coeffs) const
The ReconstructionPolynomial class allows to apply a reconstruction polynomial previously assembled.
static uint16_t countCoefficients(uint8_t degree, uint8_t dimensions)
static void evalPointBasisDerivatives(uint8_t degree, uint8_t dimensions, const std::array< double, 3 > &origin, const std::array< double, 3 > &point, const std::array< double, 3 > &direction, double *dcsi)
void computeDerivativeLimited(const std::array< double, 3 > &point, const std::array< double, 3 > &direction, const double *limiters, int field, double *derivative) const
void computeValue(const std::array< double, 3 > &point, int field, double *values) const
const double * getDegreeCoefficients(uint8_t degree, int field=0) const
void computeDerivativesLimited(const std::array< double, 3 > &point, const std::array< double, 3 > &direction, const double *limiters, double *derivatives) const
void display(std::ostream &out) const
void computeValuesLimited(const std::array< double, 3 > &point, const double *limiters, double *values) const
void initialize(uint8_t degree, uint8_t dimensions, const std::array< double, 3 > &origin, int nFields=1, bool release=true)
void swap(ReconstructionPolynomial &other) noexcept
const double * getCoefficients() const
static void evalPointBasisValues(uint8_t degree, uint8_t dimensions, const std::array< double, 3 > &origin, const std::array< double, 3 > &point, double *csi)
void computeGradientsLimited(const std::array< double, 3 > &point, const double *limiters, std::array< double, 3 > *gradients) const
static const std::vector< uint16_t > & getCoefficientsCount(uint8_t dimensions)
void computeGradients(const std::array< double, 3 > &point, std::array< double, 3 > *gradients) const
void computeDerivative(const std::array< double, 3 > &point, const std::array< double, 3 > &direction, int field, double *derivative) const
void computeGradientLimited(const std::array< double, 3 > &point, const double *limiters, int field, std::array< double, 3 > *gradient) const
static void evalCellBasisValues(uint8_t degree, uint8_t dimensions, const std::array< double, 3 > &origin, const Cell &cell, const std::array< double, 3 > *vertexCoords, double *csi)
static uint16_t getDegreeCoefficientCount(uint8_t degree, uint8_t dimensions)
void computeValueLimited(const std::array< double, 3 > &point, const double *limiters, int field, double *value) const
void computeDerivatives(const std::array< double, 3 > &point, const std::array< double, 3 > &direction, double *derivatives) const
void computeValues(const std::array< double, 3 > &point, double *values) const
ReconstructionPolynomial & operator=(const ReconstructionPolynomial &other)
const std::array< double, 3 > & getOrigin() const
static uint16_t countDegreeCoefficients(uint8_t degree, uint8_t dimensions)
static const std::vector< uint16_t > & getDegreeCoefficientsCount(uint8_t dimensions)
void computeGradient(const std::array< double, 3 > &point, int field, std::array< double, 3 > *gradient) const
The Reconstruction class allows to build and apply a polynomial reconstructions.
void clear(bool release=true)
void initialize(uint8_t degree, uint8_t dimensions, bool release=true)
Reconstruction(uint8_t degree, uint8_t dimensions)
void swap(Reconstruction &other) noexcept
--- layout: doxygen_footer ---