PolyDiM
C++ library for POLYtopal DIscretization Methods
Loading...
Searching...
No Matches
VEM_PCC_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 __VEM_PCC_Utilities_HPP
13#define __VEM_PCC_Utilities_HPP
14
15#include "Eigen/Eigen"
16#include "Gedim_Macro.hpp"
17#include "Monomials_Data.hpp"
18#include "lagrange_1D.hpp"
19
20namespace Polydim
21{
22namespace VEM
23{
24namespace PCC
25{
26
27enum struct ProjectionTypes
28{
29 Pi0km1 = 0,
30 Pi0k = 1,
31 PiNabla = 2,
32 Pi0km1Der = 3,
33 Pi0klm1 = 4
34};
35
37{
38 Eigen::VectorXd ComputeEdgeBasisCoefficients(const unsigned int &order, const Eigen::VectorXd &edgeInternalPoints) const
39 {
40 // Compute basis function coefficients on the generic edge.
41 Eigen::VectorXd interpolation_points_x(order + 1);
42 interpolation_points_x << 0.0, 1.0, edgeInternalPoints;
44 }
45
46 void ComputeL2Projectors(const double &measure,
47 const unsigned int &order,
48 const unsigned int &Nkm1,
49 const unsigned int &Nk,
50 const unsigned int &NumInternalBasisFunctions,
51 const unsigned int &NumBasisFunctions,
52 const Eigen::MatrixXd &Hmatrix,
53 const Eigen::MatrixXd &PiNabla,
54 Eigen::MatrixXd &Cmatrix,
55 Eigen::MatrixXd &Pi0km1,
56 Eigen::MatrixXd &Pi0k) const
57 {
58 Cmatrix = Eigen::MatrixXd::Zero(Nk, NumBasisFunctions);
59 // \int_E \Pi^\nabla_order \phi_j · m_i for m_i of degree > order-2 (enhancement property).
60 Cmatrix.bottomRows(Nk - NumInternalBasisFunctions) = Hmatrix.bottomRows(Nk - NumInternalBasisFunctions) * PiNabla;
61
62 if (order > 1)
63 {
64 Cmatrix.topLeftCorner(NumInternalBasisFunctions, NumBasisFunctions - NumInternalBasisFunctions).setZero();
65 //\int_E \phi_j · m_i = measure*\delta_{ij} for m_i of degree <= order-2 (internal dofs).
66 Cmatrix.topRightCorner(NumInternalBasisFunctions, NumInternalBasisFunctions) =
67 measure * Eigen::MatrixXd::Identity(NumInternalBasisFunctions, NumInternalBasisFunctions);
68 }
69
70 Pi0km1 = Hmatrix.topLeftCorner(Nkm1, Nkm1).llt().solve(Cmatrix.topRows(Nkm1));
71 Pi0k = Hmatrix.llt().solve(Cmatrix);
72 }
73
74 inline Eigen::MatrixXd EdgeDOFsCoordinates(const Eigen::RowVectorXd &referenceEdgeDOFsPoint,
75 const Eigen::MatrixXd &vertices,
76 const Eigen::MatrixXi &edges,
77 const std::vector<bool> &edgesDirection,
78 const Eigen::MatrixXd &edgesTangent,
79 const unsigned int &edge_local_index) const
80 {
81
82 const unsigned int num_edge_dofs = referenceEdgeDOFsPoint.cols();
83
84 if (num_edge_dofs == 0)
85 return Eigen::MatrixXd(0, 0);
86
87 const Eigen::Vector3d edge_origin = edgesDirection.at(edge_local_index) ? vertices.col(edges(0, edge_local_index))
88 : vertices.col(edges(1, edge_local_index));
89
90 const Eigen::Vector3d edge_tangent = edgesTangent.col(edge_local_index);
91 const double edge_direction = edgesDirection[edge_local_index] ? 1.0 : -1.0;
92
93 Eigen::MatrixXd edge_dofs_coordinates = Eigen::MatrixXd::Zero(3, num_edge_dofs);
94 for (unsigned int r = 0; r < num_edge_dofs; r++)
95 {
96 edge_dofs_coordinates.col(r) << edge_origin + edge_direction * referenceEdgeDOFsPoint(0, r) * edge_tangent;
97 }
98 return edge_dofs_coordinates;
99 }
100
101 std::vector<Eigen::MatrixXd> ComputeBasisFunctionsDerivativeValues(const unsigned int dimension,
102 const Polydim::VEM::PCC::ProjectionTypes &projectionType,
103 const unsigned int &Nkm1,
104 const Eigen::MatrixXd &vanderInternal,
105 const std::vector<Eigen::MatrixXd> &vanderInternalDerivatives,
106 const Eigen::MatrixXd &piNabla,
107 const std::vector<Eigen::MatrixXd> &pi0km1Der) const
108 {
109 switch (projectionType)
110 {
112 std::vector<Eigen::MatrixXd> basisFunctionsDerivativeValues(dimension);
113
114 for (unsigned short i = 0; i < dimension; ++i)
115 basisFunctionsDerivativeValues[i] = vanderInternalDerivatives[i] * piNabla;
116
117 return basisFunctionsDerivativeValues;
118 }
120 std::vector<Eigen::MatrixXd> basisFunctionsDerivativeValues(dimension);
121
122 for (unsigned short i = 0; i < dimension; ++i)
123 basisFunctionsDerivativeValues[i] = vanderInternal.leftCols(Nkm1) * pi0km1Der[i];
124
125 return basisFunctionsDerivativeValues;
126 }
127 default:
128 throw std::runtime_error("Unknown projector type");
129 }
130 }
131
132 Eigen::MatrixXd ComputeBasisFunctionsLaplacianValues(const unsigned int dimension,
133 const Polydim::VEM::PCC::ProjectionTypes &projectionType,
134 const unsigned int &Nkm1,
135 const std::vector<Eigen::MatrixXd> &vanderInternalDerivatives,
136 const std::vector<Eigen::MatrixXd> &pi0km1Der) const
137 {
138 switch (projectionType)
139 {
141 Eigen::MatrixXd basisFunctionsLaplacianValues = vanderInternalDerivatives[0].leftCols(Nkm1) * pi0km1Der[0];
142 for (unsigned int d = 1; d < dimension; ++d)
143 basisFunctionsLaplacianValues += vanderInternalDerivatives[d].leftCols(Nkm1) * pi0km1Der[d];
144
145 return basisFunctionsLaplacianValues;
146 }
147 default:
148 throw std::runtime_error("Unknown projector type");
149 }
150 }
151
152 inline Eigen::MatrixXd ComputeBasisFunctionsValues(const Polydim::VEM::PCC::ProjectionTypes &projectionType,
153 const unsigned int &Nkm1,
154 const Eigen::MatrixXd &pi0km1,
155 const Eigen::MatrixXd &pi0k,
156 const Eigen::MatrixXd &vanderInternal) const
157 {
158 switch (projectionType)
159 {
161 return vanderInternal.leftCols(Nkm1) * pi0km1;
163 return vanderInternal * pi0k;
164 default:
165 throw std::runtime_error("Unknown projector type");
166 }
167 }
168
169#if PYBIND == 1
170 template <typename MonomialType>
171 inline Eigen::MatrixXd ComputePolynomialsValues(const Eigen::MatrixXd &vanderInternal, const MonomialType &) const
172 {
173 return vanderInternal;
174 }
175#else
176 inline Eigen::MatrixXd ComputePolynomialsValues(const Eigen::MatrixXd &vanderInternal) const
177 {
178 return vanderInternal;
179 }
180#endif
181
182 template <typename MonomialType>
184 const MonomialType &monomials,
185 const Eigen::Vector3d &centroid,
186 const double &diameter,
187 const Eigen::MatrixXd &points) const
188 {
189 return monomials.Vander(data, points, centroid, diameter);
190 }
191
192#if PYBIND == 1
193 template <typename MonomialType>
194 inline std::vector<Eigen::MatrixXd> ComputePolynomialsDerivativeValues(const std::vector<Eigen::MatrixXd> &vanderInternalDerivatives,
195 const MonomialType &) const
196 {
197 return vanderInternalDerivatives;
198 }
199#else
200 inline std::vector<Eigen::MatrixXd> ComputePolynomialsDerivativeValues(const std::vector<Eigen::MatrixXd> &vanderInternalDerivatives) const
201 {
202 return vanderInternalDerivatives;
203 }
204#endif
205
206 template <typename MonomialType>
207 inline std::vector<Eigen::MatrixXd> ComputePolynomialsDerivativeValues(const Polydim::Utilities::Monomials_Data &data,
208 const MonomialType &monomials,
209 const double &diameter,
210 const Eigen::MatrixXd &vander) const
211 {
212 return monomials.VanderDerivatives(data, vander, diameter);
213 }
214
215 template <typename MonomialType>
217 const MonomialType &monomials,
218 const double &diameter,
219 const Eigen::MatrixXd &vander) const
220 {
221 return monomials.VanderLaplacian(data, vander, diameter);
222 }
223
224 Eigen::MatrixXd ComputeValuesOnEdge(const Eigen::RowVectorXd &edgeInternalPoints,
225 const unsigned int &order,
226 const Eigen::VectorXd &edgeBasisCoefficients,
227 const Eigen::VectorXd &pointsCurvilinearCoordinates) const
228 {
229 Eigen::VectorXd interpolation_points_x(order + 1);
230 interpolation_points_x << 0.0, 1.0, edgeInternalPoints.transpose();
231 return Polydim::Interpolation::Lagrange::Lagrange_1D_values(interpolation_points_x, edgeBasisCoefficients, pointsCurvilinearCoordinates);
232 }
233
234 Eigen::MatrixXd ComputeDofiDofiStabilizationMatrix(const Eigen::MatrixXd &projector,
235 const double &coefficient,
236 const Eigen::MatrixXd &Dmatrix) const
237 {
238 Eigen::MatrixXd stabMatrix = Dmatrix * projector;
239 stabMatrix.diagonal().array() -= 1;
240 // stabMatrix = (\Pi^{\nabla,dofs}_order - I)^T * (\Pi^{\nabla,dofs}_order - I).
241 stabMatrix = coefficient * stabMatrix.transpose() * stabMatrix;
242 return stabMatrix;
243 }
244
245 Eigen::MatrixXd ComputeDRecipeStabilizationMatrix(const Eigen::MatrixXd &projector,
246 const Eigen::MatrixXd &coercivity_matrix,
247 const Eigen::VectorXd &vector_coefficients,
248 const Eigen::MatrixXd &Dmatrix) const
249 {
250 Eigen::MatrixXd stabMatrix = Dmatrix * projector;
251 stabMatrix.diagonal().array() -= 1;
252
253 const Eigen::VectorXd diagonal_coercivity = coercivity_matrix.diagonal();
254 Eigen::MatrixXd max_matrix = Eigen::MatrixXd::Zero(coercivity_matrix.cols(), 2);
255 max_matrix << diagonal_coercivity, vector_coefficients;
256
257 const Eigen::VectorXd weights = max_matrix.rowwise().maxCoeff();
258
259 // stabMatrix = (\Pi^{\nabla,dofs}_order - I)^T * (\Pi^{\nabla,dofs}_order - I).
260 stabMatrix = stabMatrix.transpose() * weights.asDiagonal() * stabMatrix;
261
262 return stabMatrix;
263 }
264};
265} // namespace PCC
266} // namespace VEM
267} // namespace Polydim
268
269#endif
Eigen::VectorXd Lagrange_1D_coefficients(const Eigen::VectorXd &interpolation_points_x)
Compute the barycentric weights of the 1D Lagrange basis.
Definition lagrange_1D.cpp:21
Eigen::MatrixXd Lagrange_1D_values(const Eigen::VectorXd &interpolation_points_x, const Eigen::VectorXd &lagrange_1D_coefficients, const Eigen::VectorXd &evaluation_points_x)
Evaluate the 1D Lagrange basis functions at given points.
Definition lagrange_1D.cpp:55
ProjectionTypes
Definition VEM_PCC_Utilities.hpp:28
Definition FEM_MCC_2D_LocalSpace.cpp:17
Definition Monomials_Data.hpp:23
Definition VEM_PCC_Utilities.hpp:37
Eigen::MatrixXd ComputePolynomialsValues(const Eigen::MatrixXd &vanderInternal) const
Definition VEM_PCC_Utilities.hpp:176
std::vector< Eigen::MatrixXd > ComputePolynomialsDerivativeValues(const Polydim::Utilities::Monomials_Data &data, const MonomialType &monomials, const double &diameter, const Eigen::MatrixXd &vander) const
Definition VEM_PCC_Utilities.hpp:207
std::vector< Eigen::MatrixXd > ComputeBasisFunctionsDerivativeValues(const unsigned int dimension, const Polydim::VEM::PCC::ProjectionTypes &projectionType, const unsigned int &Nkm1, const Eigen::MatrixXd &vanderInternal, const std::vector< Eigen::MatrixXd > &vanderInternalDerivatives, const Eigen::MatrixXd &piNabla, const std::vector< Eigen::MatrixXd > &pi0km1Der) const
Definition VEM_PCC_Utilities.hpp:101
Eigen::MatrixXd ComputeBasisFunctionsLaplacianValues(const unsigned int dimension, const Polydim::VEM::PCC::ProjectionTypes &projectionType, const unsigned int &Nkm1, const std::vector< Eigen::MatrixXd > &vanderInternalDerivatives, const std::vector< Eigen::MatrixXd > &pi0km1Der) const
Definition VEM_PCC_Utilities.hpp:132
std::vector< Eigen::MatrixXd > ComputePolynomialsDerivativeValues(const std::vector< Eigen::MatrixXd > &vanderInternalDerivatives) const
Definition VEM_PCC_Utilities.hpp:200
void ComputeL2Projectors(const double &measure, const unsigned int &order, const unsigned int &Nkm1, const unsigned int &Nk, const unsigned int &NumInternalBasisFunctions, const unsigned int &NumBasisFunctions, const Eigen::MatrixXd &Hmatrix, const Eigen::MatrixXd &PiNabla, Eigen::MatrixXd &Cmatrix, Eigen::MatrixXd &Pi0km1, Eigen::MatrixXd &Pi0k) const
Definition VEM_PCC_Utilities.hpp:46
Eigen::MatrixXd ComputeBasisFunctionsValues(const Polydim::VEM::PCC::ProjectionTypes &projectionType, const unsigned int &Nkm1, const Eigen::MatrixXd &pi0km1, const Eigen::MatrixXd &pi0k, const Eigen::MatrixXd &vanderInternal) const
Definition VEM_PCC_Utilities.hpp:152
Eigen::MatrixXd ComputeDRecipeStabilizationMatrix(const Eigen::MatrixXd &projector, const Eigen::MatrixXd &coercivity_matrix, const Eigen::VectorXd &vector_coefficients, const Eigen::MatrixXd &Dmatrix) const
Definition VEM_PCC_Utilities.hpp:245
Eigen::VectorXd ComputeEdgeBasisCoefficients(const unsigned int &order, const Eigen::VectorXd &edgeInternalPoints) const
Definition VEM_PCC_Utilities.hpp:38
Eigen::MatrixXd EdgeDOFsCoordinates(const Eigen::RowVectorXd &referenceEdgeDOFsPoint, const Eigen::MatrixXd &vertices, const Eigen::MatrixXi &edges, const std::vector< bool > &edgesDirection, const Eigen::MatrixXd &edgesTangent, const unsigned int &edge_local_index) const
Definition VEM_PCC_Utilities.hpp:74
Eigen::MatrixXd ComputeValuesOnEdge(const Eigen::RowVectorXd &edgeInternalPoints, const unsigned int &order, const Eigen::VectorXd &edgeBasisCoefficients, const Eigen::VectorXd &pointsCurvilinearCoordinates) const
Definition VEM_PCC_Utilities.hpp:224
Eigen::MatrixXd ComputePolynomialsValues(const Polydim::Utilities::Monomials_Data &data, const MonomialType &monomials, const Eigen::Vector3d &centroid, const double &diameter, const Eigen::MatrixXd &points) const
Definition VEM_PCC_Utilities.hpp:183
Eigen::MatrixXd ComputePolynomialsLaplacianValues(const Polydim::Utilities::Monomials_Data &data, const MonomialType &monomials, const double &diameter, const Eigen::MatrixXd &vander) const
Definition VEM_PCC_Utilities.hpp:216
Eigen::MatrixXd ComputeDofiDofiStabilizationMatrix(const Eigen::MatrixXd &projector, const double &coefficient, const Eigen::MatrixXd &Dmatrix) const
Definition VEM_PCC_Utilities.hpp:234