PolyDiM
C++ library for POLYtopal DIscretization Methods
Loading...
Searching...
No Matches
Monomials_Utilities.hpp
Go to the documentation of this file.
1// _LICENSE_HEADER_
2//
3// Copyright (C) 2019 - 2025.
4// Terms register on the GPL-3.0 license.
5//
6// This file can be redistributed and/or modified under the license terms.
7//
8// See top level LICENSE file for more details.
9//
10// This file can be used citing references in CITATION.cff file.
11
12#ifndef __Monomials_Utilities_HPP
13#define __Monomials_Utilities_HPP
14
15#include "LAPACK_utilities.hpp"
16#include "Monomials_Data.hpp"
17
18namespace Polydim
19{
20namespace Utilities
21{
22template <unsigned short dimension> struct Monomials_Utilities final
23{
29 Eigen::MatrixXi Exponents(const Polydim::Utilities::Monomials_Data &data) const
30 {
31 Eigen::MatrixXi exponents(dimension, data.NumMonomials);
32
33 for (unsigned int m = 0; m < data.NumMonomials; m++)
34 exponents.col(m) << data.Exponents[m];
35
36 return exponents;
37 }
38
53 Eigen::MatrixXd Vander(const Polydim::Utilities::Monomials_Data &data,
54 const Eigen::MatrixXd &points,
55 const Eigen::Vector3d &centroid,
56 const double &diam) const
57 {
58 Eigen::MatrixXd vander;
59 const unsigned int numPoints = points.cols();
60 if (data.NumMonomials > 1)
61 {
62 // VanderPartial[i]'s rows contain (x-x_E)^i/h_E^i,
63 // (y-y_E)^i/h_E^i and (possibly) (z-z_E)^i/h_E^i respectively.
64 // Size is dimension x numPoints.
65 std::vector<Eigen::MatrixXd> VanderPartial(data.PolynomialDegree + 1, Eigen::MatrixXd(dimension, numPoints));
66 double inverseDiam = 1.0 / diam;
67 VanderPartial[0].setOnes(dimension, numPoints);
68 VanderPartial[1] = (points.colwise() - centroid) * inverseDiam;
69
70 for (unsigned int i = 2; i <= data.PolynomialDegree; i++)
71 VanderPartial[i] = VanderPartial[i - 1].cwiseProduct(VanderPartial[1]);
72
73 vander.resize(numPoints, data.NumMonomials);
74 vander.col(0).setOnes();
75 for (unsigned int i = 1; i < data.NumMonomials; ++i)
76 {
77 const Eigen::VectorXi expo = data.Exponents[i];
78
79 vander.col(i) = (VanderPartial[expo[0]].row(0)).transpose();
80 if (dimension > 1)
81 vander.col(i) = vander.col(i).cwiseProduct(VanderPartial[expo[1]].row(1).transpose());
82 if (dimension > 2)
83 vander.col(i) = vander.col(i).cwiseProduct(VanderPartial[expo[2]].row(2).transpose());
84 }
85 }
86 else
87 vander.setOnes(numPoints, 1);
88
89 return vander;
90 }
91
107 template <typename MonomialType>
108 std::vector<Eigen::MatrixXd> VanderDerivatives(const Polydim::Utilities::Monomials_Data &data,
109 const MonomialType &monomials,
110 const Eigen::MatrixXd &Vander,
111 const double &diam) const
112 {
113 std::vector<Eigen::MatrixXd> vanderDerivatives;
114 vanderDerivatives.resize(dimension);
115 for (unsigned int i = 0; i < dimension; i++)
116 {
117 vanderDerivatives[i].resizeLike(Vander);
118 vanderDerivatives[i].col(0).setZero();
119 }
120 if (data.NumMonomials > 1)
121 {
122 double inverseDiam = 1.0 / diam;
123 for (unsigned int k = 1; k < data.NumMonomials; k++)
124 {
125 std::vector<int> derIndices = monomials.DerivativeIndices(data, k);
126 for (unsigned int i = 0; i < dimension; i++)
127 {
128 if (derIndices[i] >= 0)
129 vanderDerivatives[i].col(k) =
130 inverseDiam * monomials.DerivativeMatrix(data, i)(k, derIndices[i]) * Vander.col(derIndices[i]);
131 else
132 vanderDerivatives[i].col(k).setZero();
133 }
134 }
135 }
136
137 return vanderDerivatives;
138 }
139
154 template <typename MonomialType>
156 const MonomialType &monomials,
157 const Eigen::MatrixXd &Vander,
158 const double &diam) const
159 {
160 Eigen::MatrixXd vanderLaplacian;
161
162 vanderLaplacian.resizeLike(Vander);
163 vanderLaplacian.block(0, 0, Vander.rows(), 3).setZero();
164 Eigen::MatrixXd laplacian = data.Laplacian;
165
166 if (data.NumMonomials > 3)
167 {
168 const double inverseDiamSqrd = 1.0 / (diam * diam);
169 for (unsigned int k = 3; k < data.NumMonomials; k++)
170 {
171 std::vector<int> secondDerIndices = monomials.SecondDerivativeIndices(data, k);
172 if (secondDerIndices[0] >= 0)
173 vanderLaplacian.col(k) =
174 inverseDiamSqrd * laplacian(k, secondDerIndices[0]) * Vander.col(secondDerIndices[0]);
175 else
176 vanderLaplacian.col(k).setZero();
177 for (unsigned int i = 1; i < dimension; i++)
178 {
179 if (secondDerIndices[i] >= 0)
180 vanderLaplacian.col(k) +=
181 inverseDiamSqrd * laplacian(k, secondDerIndices[i]) * Vander.col(secondDerIndices[i]);
182 }
183 }
184 }
185
186 return vanderLaplacian;
187 }
188
202 void MGSOrthonormalize(const Eigen::VectorXd &weights,
203 const Eigen::MatrixXd &Vander,
204 Eigen::MatrixXd &Hmatrix,
205 Eigen::MatrixXd &QmatrixInv,
206 Eigen::MatrixXd &Qmatrix) const
207 {
208 Eigen::MatrixXd Q1;
209 Eigen::MatrixXd R1;
211
212 // L2(E)-re-orthogonalization process
213 Eigen::MatrixXd Q2;
214 Eigen::MatrixXd R2;
215 LAPACK_utilities::MGS(weights.array().sqrt().matrix().asDiagonal() * Q1, Q2, R2);
216
217 Hmatrix = Q2.transpose() * Q2;
218
219 QmatrixInv = (R2 * R1).transpose();
220 LAPACK_utilities::inverseTri(QmatrixInv, Qmatrix, 'L', 'N');
221 }
222};
223} // namespace Utilities
224} // namespace Polydim
225
226#endif
void inverseTri(const Eigen::MatrixXd A, Eigen::MatrixXd &InvA, const char &UPLO, const char &DIAG)
Compute inverse of triangular matrix.
Definition LAPACK_utilities.cpp:198
void MGS(const Eigen::MatrixXd &X, Eigen::MatrixXd &Q, Eigen::MatrixXd &R)
Compute the modified Gram-Schmidt factorization of matrix X.
Definition LAPACK_utilities.cpp:92
Definition FEM_MCC_2D_LocalSpace.cpp:17
Definition Monomials_Data.hpp:23
Eigen::MatrixXd Laplacian
Matrix used to compute the laplacian of monomials.
Definition Monomials_Data.hpp:29
std::vector< Eigen::VectorXi > Exponents
Table of exponents of each monomial.
Definition Monomials_Data.hpp:27
unsigned int PolynomialDegree
Monomial space order.
Definition Monomials_Data.hpp:24
unsigned int NumMonomials
Number of monomials in the basis.
Definition Monomials_Data.hpp:26
Definition Monomials_Utilities.hpp:23
Eigen::MatrixXd VanderLaplacian(const Polydim::Utilities::Monomials_Data &data, const MonomialType &monomials, const Eigen::MatrixXd &Vander, const double &diam) const
Evaluate the Vandermonde matrix of the monomial Laplacian.
Definition Monomials_Utilities.hpp:155
void MGSOrthonormalize(const Eigen::VectorXd &weights, const Eigen::MatrixXd &Vander, Eigen::MatrixXd &Hmatrix, Eigen::MatrixXd &QmatrixInv, Eigen::MatrixXd &Qmatrix) const
-orthonormalize the monomial basis via modified Gram–Schmidt.
Definition Monomials_Utilities.hpp:202
Eigen::MatrixXi Exponents(const Polydim::Utilities::Monomials_Data &data) const
Collect the monomial exponents into a single matrix.
Definition Monomials_Utilities.hpp:29
Eigen::MatrixXd Vander(const Polydim::Utilities::Monomials_Data &data, const Eigen::MatrixXd &points, const Eigen::Vector3d &centroid, const double &diam) const
Evaluate the Vandermonde matrix of the scaled monomial basis.
Definition Monomials_Utilities.hpp:53
std::vector< Eigen::MatrixXd > VanderDerivatives(const Polydim::Utilities::Monomials_Data &data, const MonomialType &monomials, const Eigen::MatrixXd &Vander, const double &diam) const
Evaluate the Vandermonde matrices of the first-order partial derivatives.
Definition Monomials_Utilities.hpp:108