Bembel
 
Loading...
Searching...
No Matches
Bezierextraction.hpp
1// This file is part of Bembel, the higher order C++ boundary element library.
2//
3// Copyright (C) 2022 see <http://www.bembel.eu>
4//
5// It was written as part of a cooperation of J. Doelz, H. Harbrecht, S. Kurz,
6// M. Multerer, S. Schoeps, and F. Wolf at Technische Universitaet Darmstadt,
7// Universitaet Basel, and Universita della Svizzera italiana, Lugano. This
8// source code is subject to the GNU General Public License version 3 and
9// provided WITHOUT ANY WARRANTY, see <http://www.bembel.eu> for further
10// information.
11#ifndef BEMBEL_SRC_SPLINE_BEZIEREXTRACTION_HPP_
12#define BEMBEL_SRC_SPLINE_BEZIEREXTRACTION_HPP_
13
14namespace Bembel {
15namespace Spl {
16
22template <typename T>
23Eigen::SparseMatrix<T> MakeProjection(const std::vector<T> &x_knots,
24 const std::vector<T> &y_knots,
25 const std::vector<T> &x_unique_knots,
26 const std::vector<T> &y_unique_knots,
27 const int polynomial_degree_x,
28 const int polynomial_degree_y) noexcept {
29 // In here phi refers to the BIG bezier basis, and psi refers to the small
30 // B-Spline basis given by x_knots,y_knots and xp,yp.
31 // Sparse does weird things. We need not be that accurate, since the right
32 // coeefs will be >=.1
33 constexpr double sparseTol = 0.001;
34 // Number of functions in X,Y and total
35 const int size_phi_x = (x_unique_knots.size() - 1) * polynomial_degree_x;
36 const int size_phi_y = (y_unique_knots.size() - 1) * polynomial_degree_y;
37 const int size_phi = size_phi_x * size_phi_y;
38 const int size_psi_x = x_knots.size() - polynomial_degree_x;
39 const int size_psi_y = y_knots.size() - polynomial_degree_y;
40 const int size_psi = size_psi_x * size_psi_y;
41
42 // Interpolation points
43 const auto xmask = MakeInterpolationMask(polynomial_degree_x);
44 const auto ymaks = MakeInterpolationMask(polynomial_degree_y);
45
48
49 assert(((int)(xmask.size() * (x_unique_knots.size() - 1))) == size_phi_x);
50 assert(((int)(xpoint.size())) == size_phi_x);
51 assert(((int)(ypoint.size())) == size_phi_y);
52
53 Eigen::Matrix<T, -1, -1> tempsolver =
54 Eigen::Matrix<T, -1, -1>::Zero(size_phi, size_phi);
55
56 double *coefficients_x = new double[polynomial_degree_x];
57 double *coefficients_y = new double[polynomial_degree_y];
58
59 for (int i = 0; i < polynomial_degree_x; i++) coefficients_x[i] = 0;
60
61 for (int i = 0; i < polynomial_degree_y; i++) coefficients_y[i] = 0;
62
63 auto BezBasis = [](std::vector<double> uniq, int deg, int pos, double pt,
64 double *coef) {
65 std::div_t loc = std::div(pos, deg);
66 if (pt > uniq[loc.quot + 1] || pt < uniq[loc.quot]) {
67 return 0.;
68 } else {
69 coef[loc.rem] = 1;
70 double out = Bembel::Basis::ShapeFunctionHandler::evalCoef(
71 deg - 1, coef, Rescale(pt, uniq[loc.quot], uniq[loc.quot + 1]));
72 coef[loc.rem] = 0;
73 return out;
74 }
75 };
76
77 // A matrix, each row corresponds to one tp-basisfunction, each col to one
78 // tp-interpolation point
79 for (int iy = 0; iy < size_phi_y; iy++) {
80 for (int ix = 0; ix < size_phi_x; ix++) {
81 for (int y = 0; y < size_phi_y; y++) {
82 for (int x = 0; x < size_phi_x; x++) {
88 }
89 }
90 }
91 }
92
93 delete[] coefficients_x;
94 delete[] coefficients_y;
95
96 Eigen::FullPivLU<Eigen::Matrix<double, -1, -1>> lu_decomp(tempsolver);
97 assert(lu_decomp.rank() == size_phi);
99 Eigen::Matrix<T, -1, -1> solve = tempsolver.inverse();
100
101 Eigen::Matrix<T, -1, -1> Proj(size_phi, size_psi);
102 Eigen::Matrix<T, -1, -1> unit =
103 Eigen::Matrix<T, -1, -1>::Zero(size_psi_y, size_psi_x);
104
106 for (int i = 0; i < size_psi_x; i++)
107 for (int j = 0; j < size_psi_y; j++) {
108 unit(j, i) = 1.;
109 Eigen::Matrix<T, -1, 1> smallBase =
111 Proj.col(i * size_psi_y + j) = (solve * smallBase).transpose();
112 unit(j, i) = 0.;
113 }
114
115 return (Proj.sparseView()).pruned(sparseTol);
116}
117} // namespace Spl
118} // namespace Bembel
119#endif // BEMBEL_SRC_SPLINE_BEZIEREXTRACTION_HPP_
Eigen::SparseMatrix< T > MakeProjection(const std::vector< T > &x_knots, const std::vector< T > &y_knots, const std::vector< T > &x_unique_knots, const std::vector< T > &y_unique_knots, const int polynomial_degree_x, const int polynomial_degree_y) noexcept
implements Bezier extraction via the solution of an interpolation problem.
std::vector< T > MakeInterpolationPoints(const std::vector< T > &uniq, const std::vector< T > &mask) noexcept
Creates a T-vector of equidistant itnerpolation points for a given knot vector without any repetition...
Definition Localize.hpp:47
Eigen::Matrix< T, -1, 1 > Unroll(const Eigen::Matrix< T, -1, -1 > &input_matrix) noexcept
Tiny helper functions.
Definition Unroll.hpp:23
Eigen::Matrix< T, -1, -1 > DeBoorTP(Eigen::Matrix< T, -1, -1 > const &control_points, std::vector< double > const &knots_x, std::vector< double > const &knots_y, std::vector< double > const &evaluation_points_x, std::vector< double > const &evaluation_points_y) noexcept
Simple TP Bsplines.
Definition DeBoorTP.hpp:99
Routines for the evalutation of pointwise errors.
constexpr int getFunctionSpaceOutputDimension()