HArD::Core2D
Hybrid Arbitrary Degree::Core 2D - Library to implement 2D schemes with edge and cell polynomials as unknowns
Loading...
Searching...
No Matches
xrotrot.hpp
Go to the documentation of this file.
1#ifndef XROTROT_HPP
2#define XROTROT_HPP
3
4#include <globaldofspace.hpp>
5#include <ddrcore.hpp>
6#include <integralweight.hpp>
7#include <xgrad.hpp>
8#include <xrot.hpp>
9#include <GMpoly_cell.hpp>
10
11namespace HArDCore2D
12{
19 class XRotRot : public GlobalDOFSpace
20 {
21 public:
22 typedef std::function<Eigen::Vector2d(const Eigen::Vector2d &)> FunctionType;
23 typedef std::function<double(const Eigen::Vector2d &)> RotType;
24
27 {
29 const Eigen::MatrixXd & _rotor,
30 const Eigen::MatrixXd & _potential
31 )
32 : rotor(_rotor),
33 potential(_potential)
34 {
35 // Do nothing
36 }
37
38 Eigen::MatrixXd rotor;
39 Eigen::MatrixXd potential;
40 };
41
43 XRotRot(const DDRCore & ddr_core, bool use_threads = true, std::ostream & output = std::cout);
44
46 const Mesh & mesh() const
47 {
48 return m_ddr_core.mesh();
49 }
50
52 const size_t & degree() const
53 {
54 return m_ddr_core.degree();
55 }
56
58 Eigen::VectorXd interpolate(
59 const FunctionType & v,
60 const RotType & rot_v,
61 const int deg_quad = -1
62 ) const;
63
65 inline const LocalOperators & cellOperators(size_t iT) const
66 {
67 return *m_cell_operators[iT];
68 }
69
71 inline const LocalOperators & cellOperators(const Cell & T) const
72 {
73 return * m_cell_operators[T.global_index()];
74 }
75
77 inline Eigen::MatrixXd cellRotor(size_t iT) const
78 {
79 const Cell & T = *mesh().cell(iT);
81 }
82
84 inline Eigen::MatrixXd cellRotor(const Cell & T) const
85 {
86 return cellRotor(T.global_index());
87 }
88
90 inline const DDRCore::CellBases & cellBases(size_t iT) const
91 {
92 return m_ddr_core.cellBases(iT);
93 }
94
96 inline const DDRCore::CellBases & cellBases(const Cell & T) const
97 {
98 return m_ddr_core.cellBases(T.global_index());
99 }
100
102 inline const DDRCore::EdgeBases & edgeBases(size_t iE) const
103 {
104 return m_ddr_core.edgeBases(iE);
105 }
106
108 inline const DDRCore::EdgeBases & edgeBases(const Edge & E) const
109 {
110 return m_ddr_core.edgeBases(E.global_index());
111 }
112
114 // The mass matrix of P^k(T)^2 is the most expensive mass matrix in the calculation of this norm, which
115 // is why there's the option of passing it as parameter if it's been already pre-computed when the norm is called.
116 Eigen::MatrixXd computeL2Product(
117 size_t iT,
118 const double & penalty_factor = 1.,
119 const IntegralWeight & weight = IntegralWeight(1.)
120 ) const;
121
123 Eigen::MatrixXd computeGradientPotentialL2Product(
124 size_t iT,
125 const XGrad * x_grad,
126 const double & penalty_factor = 1.,
127 const IntegralWeight & weight = IntegralWeight(1.)
128 ) const;
129
131 Eigen::MatrixXd computeGradientL2Product(
132 size_t iT,
133 const XGrad * x_grad,
134 const double & penalty_factor = 1.,
135 const IntegralWeight & weight = IntegralWeight(1.)
136 ) const;
137
138
140 template<typename LeftOperatorFillerType, typename RightOperatorFillerType>
142 size_t iT,
143 const double & penalty_factor,
144 const IntegralWeight & weight,
145 LeftOperatorFillerType fillLeftOp,
146 RightOperatorFillerType fillRightOp
147 ) const;
148
150 double computeL2Norm(const Eigen::VectorXd & v) const;
151
154 const Eigen::VectorXd & v,
155 const XGrad * x_grad
156 ) const;
157
158 private:
159 LocalOperators _compute_cell_rotor_potential(size_t iT);
160 double _compute_squared_l2_norm(size_t iT, const Eigen::VectorXd & vT) const;
161 double _compute_squared_gradient_l2_norm(
162 size_t iT,
163 const XGrad * x_grad,
164 const Eigen::VectorXd & vT
165 ) const;
166
167 const DDRCore & m_ddr_core;
168 bool m_use_threads;
169 std::ostream & m_output;
170
171 // DOFs for the rot (these DOFs coincide with those of XRot)
172 GlobalDOFSpace m_rot_dofs;
173
174 // Containers for local operators
175 std::vector<std::unique_ptr<LocalOperators> > m_cell_operators;
176
177 };
178
179 //------------------------------------------------------------------------------
180 // Implementation of template functions
181 //------------------------------------------------------------------------------
182
183 template<typename LeftOperatorFillerType, typename RightOperatorFillerType>
185 size_t iT,
186 const double & penalty_factor,
187 const IntegralWeight & weight,
188 LeftOperatorFillerType fillLeftOp,
189 RightOperatorFillerType fillRightOp
190 ) const
191 {
192 const Cell & T = *mesh().cell(iT);
193
194 // Create the weighted mass matrix, with simple product if weight is constant
195 Eigen::MatrixXd w_mass_Pk2_T;
196 if (weight.deg(T) == 0) { // Constant weight
198 w_mass_Pk2_T = weight.value(T, T.center_mass()) * GramMatrix(T, *cellBases(iT).Polyk2, int_mono_2kp2);
199 } else { // Weight is not constant, we create a weighted mass matrix
200 QuadratureRule quad_2kpw_T = generate_quadrature_rule(T, 2 * degree() + weight.deg(T));
201 auto basis_Pk2_T_quad = evaluate_quad<Function>::compute(*cellBases(iT).Polyk2, quad_2kpw_T);
202 std::function<double(const Eigen::Vector2d &)> weight_T
203 = [&T, &weight](const Eigen::Vector2d &x)->double {
204 return weight.value(T, x);
205 };
206 w_mass_Pk2_T = compute_weighted_gram_matrix(weight_T, basis_Pk2_T_quad, basis_Pk2_T_quad, quad_2kpw_T, "sym");
207 }
208
209 // Fill left-hand side and right-hand side operators
210 std::vector<Eigen::MatrixXd> leftOp = fillLeftOp(iT);
211 std::vector<Eigen::MatrixXd> rightOp = fillRightOp(iT);
212
213 // Compute the L2-product
214 double hT = T.diam();
215
216 size_t offset_PT = T.n_vertices() + 2 * T.n_edges();
217 size_t offset_RT = offset_PT + 1;
218
219 Eigen::MatrixXd L2P = Eigen::MatrixXd::Zero(leftOp[0].cols(), rightOp[0].cols());
220
221 // Vertex penalty terms
222 for (size_t iV = 0; iV < T.n_vertices(); iV++) {
223 const Vertex & V = *T.vertex(iV);
224 VectorRd xV = V.coords();
225 Eigen::MatrixXd basis_PkT_xV = Eigen::MatrixXd::Zero(1, cellBases(iT).Polyk->dimension());
226 for (size_t i = 0; i < cellBases(iT).Polyk->dimension(); i++) {
227 basis_PkT_xV(0, i) = cellBases(iT).Polyk->function(i, xV);
228 } // for
229 Eigen::MatrixXd left_RT_xV = basis_PkT_xV * leftOp[offset_RT];
230 Eigen::MatrixXd right_RT_xV = basis_PkT_xV * rightOp[offset_RT];
231
232 double w_hT4_xV = weight.value(T, xV) * std::pow(hT, 4);
233 L2P += w_hT4_xV * (left_RT_xV - leftOp[iV]).transpose() * (right_RT_xV - rightOp[iV]);
234 } // for iV
235
236 // Edge penalty terms
237 for (size_t iE = 0; iE < T.n_edges(); iE++) {
238 const Edge & E = *T.edge(iE);
239 VectorRd tE = E.tangent();
240
241 size_t offset_PE = T.n_vertices() + 2 * iE;
242 size_t offset_RE = offset_PE + 1;
243
244 QuadratureRule quad_2k_E = generate_quadrature_rule(E, 2 * degree());
245
246 // Weight and scaling hE
247 double max_weight_quad_E = weight.value(T, quad_2k_E[0].vector());
248 // If the weight is not constant, we want to take the largest along the edge
249 if (weight.deg(T)>0) {
250 for (size_t iqn = 1; iqn < quad_2k_E.size(); iqn++) {
251 max_weight_quad_E = std::max(max_weight_quad_E, weight.value(T, quad_2k_E[iqn].vector()));
252 } // for
253 } // if
254 double w_hE = max_weight_quad_E * E.measure();
255
256 // Penalty term h_E int_E (PT w . tE - w_E) * (PT v . tE - v_E)
257 auto basis_Pk2_T_dot_tE_quad = scalar_product(evaluate_quad<Function>::compute(*cellBases(iT).Polyk2, quad_2k_E), tE);
258 auto basis_Pk_E_quad = evaluate_quad<Function>::compute(*edgeBases(E).Polyk, quad_2k_E);
259 Eigen::MatrixXd gram_Pk2T_dot_tE_PkE = compute_gram_matrix(basis_Pk2_T_dot_tE_quad, basis_Pk_E_quad, quad_2k_E);
260
261 L2P += w_hE * (
262 leftOp[offset_PT].transpose() * compute_gram_matrix(basis_Pk2_T_dot_tE_quad, quad_2k_E) * rightOp[offset_PT]
263 - leftOp[offset_PT].transpose() * gram_Pk2T_dot_tE_PkE * rightOp[offset_PE]
264 - leftOp[offset_PE].transpose() * gram_Pk2T_dot_tE_PkE.transpose() * rightOp[offset_PT]
265 + leftOp[offset_PE].transpose() * compute_gram_matrix(basis_Pk_E_quad, quad_2k_E) * rightOp[offset_PE]
266 );
267
268 if(degree() >= 1) {
269 double w_hE3 = max_weight_quad_E * pow(E.measure(), 3);
270
271 // Penalty term h_E^3 \int_E (pi^{k-1}_E RT w - C_{w,E}) * (pi^{k-1}_E RT v - C_{v,E})
272 auto basis_PkT_E_quad = evaluate_quad<Function>::compute(*cellBases(iT).Polyk, quad_2k_E);
273 auto basis_PkmoT_E_quad = evaluate_quad<Function>::compute(*cellBases(iT).Polykmo, quad_2k_E);
274 auto basis_PkmoE_E_quad = evaluate_quad<Function>::compute(*edgeBases(E).Polykmo, quad_2k_E);
275
276 Eigen::MatrixXd mass_PkmoE = compute_gram_matrix(basis_PkmoE_E_quad, quad_2k_E);
277 Eigen::MatrixXd gram_PkT_PkmoE = compute_gram_matrix(basis_PkT_E_quad, basis_PkmoE_E_quad, quad_2k_E);
278 Eigen::MatrixXd gram_PkmoT_PkmoE = compute_gram_matrix(basis_PkmoT_E_quad, basis_PkmoE_E_quad, quad_2k_E);
279
280 // Compute the projections on Pk-1(E) of the left and right "rotor" operators
281 Eigen::PartialPivLU<Eigen::MatrixXd> lu_mass_PkmoE(mass_PkmoE);
282 Eigen::MatrixXd pikmoE_left_RT = lu_mass_PkmoE.solve(gram_PkT_PkmoE.transpose() * leftOp[offset_RT]);
283 Eigen::MatrixXd pikmoE_right_RT = lu_mass_PkmoE.solve(gram_PkT_PkmoE.transpose() * rightOp[offset_RT]);
284
285 L2P += w_hE3 * (pikmoE_left_RT - leftOp[offset_RE]).transpose() * mass_PkmoE * (pikmoE_right_RT - rightOp[offset_RE]);
286 } // if
287 } // for iE
288
289 L2P *= penalty_factor;
290
291 // Consistent (cell) term
292 L2P += leftOp[offset_PT].transpose() * w_mass_Pk2_T * rightOp[offset_PT];
293
294 return L2P;
295 }
296
297} // end of namespace HArDCore2D
298#endif
Construct all polynomial spaces for the DDR sequence.
Definition ddrcore.hpp:63
Base class for global DOF spaces. Provides functions to manipulate global DOFs (the local version bei...
Definition globaldofspace.hpp:16
Discrete H1 space: local operators, L2 product and global interpolator.
Definition xgrad.hpp:17
Discrete HRotRot space: local operators, L2 product and global interpolator.
Definition xrotrot.hpp:20
Definition Mesh2D.hpp:26
Compute max and min eigenvalues of all matrices for i
Definition compute_eigs.m:5
Eigen::Vector2d VectorRd
Definition basis.hpp:55
double scalar_product(const double &x, const double &y)
Scalar product between two reals.
Definition basis.cpp:163
Eigen::MatrixXd compute_gram_matrix(const boost::multi_array< VectorRd, 2 > &B1, const boost::multi_array< double, 2 > &B2, const QuadratureRule &qr)
Compute the Gram-like matrix given a family of vector-valued and one of scalar-valued functions by te...
Definition basis.cpp:225
Eigen::MatrixXd compute_weighted_gram_matrix(const FType< VectorRd > &f, const BasisQuad< VectorRd > &B1, const BasisQuad< double > &B2, const QuadratureRule &qr, size_t n_rows, size_t n_cols)
Computes the Gram-like matrix of integrals (f dot phi_i, phi_j)
Definition basis.cpp:354
static boost::multi_array< typename detail::basis_evaluation_traits< BasisType, BasisFunction >::ReturnValue, 2 > compute(const BasisType &basis, const QuadratureRule &quad)
Generic basis evaluation.
Definition basis.hpp:2288
size_t localOffset(const Edge &E, const Vertex &V) const
Returns the local offset of the vertex V with respect to the edge E.
Definition localdofspace.hpp:143
std::function< double(const Cell &T, const Eigen::Vector2d &x)> value
Definition integralweight.hpp:52
std::function< size_t(const Cell &T)> deg
Definition integralweight.hpp:53
size_t dimensionCell(const Cell &T) const
Returns the dimension of the local space on the cell T (including faces, edges and vertices)
Definition localdofspace.hpp:112
Eigen::MatrixXd computeGradientL2Product(size_t iT, const XGrad *x_grad, const double &penalty_factor=1., const IntegralWeight &weight=IntegralWeight(1.)) const
Compute the matrix of the (weighted) gradient-gradient L2-product.
Definition xrotrot.cpp:277
const Mesh & mesh() const
Return a const reference to the mesh.
Definition ddrcore.hpp:115
Eigen::MatrixXd computeGradientPotentialL2Product(size_t iT, const XGrad *x_grad, const double &penalty_factor=1., const IntegralWeight &weight=IntegralWeight(1.)) const
Compute the matrix of the (weighted) L2-product as 'computeL2Product', with application of the discre...
Definition xrotrot.cpp:256
const DDRCore::EdgeBases & edgeBases(size_t iE) const
Return edge bases for the edge of index iE.
Definition xrotrot.hpp:102
const size_t & degree() const
Return the polynomial degree.
Definition ddrcore.hpp:121
Eigen::MatrixXd cellRotor(size_t iT) const
Return cell rotor for cell of index iT.
Definition xrotrot.hpp:77
const Mesh & mesh() const
Return the mesh.
Definition xrotrot.hpp:46
double computeL2Norm(const Eigen::VectorXd &v) const
Compute the L2-norm of a vector of the space.
Definition xrotrot.cpp:320
Eigen::MatrixXd computeL2ProductWithOperatorFillers(size_t iT, const double &penalty_factor, const IntegralWeight &weight, LeftOperatorFillerType fillLeftOp, RightOperatorFillerType fillRightOp) const
Compute the matrix of the L2 product given operators filling functions.
Definition xrotrot.hpp:184
double computeGradientL2Norm(const Eigen::VectorXd &v, const XGrad *x_grad) const
Compute the L2-norm of the discrete gradient of a vector in XGrad.
Definition xrotrot.cpp:339
const LocalOperators & cellOperators(const Cell &T) const
Return cell operators for cell T.
Definition xrotrot.hpp:71
const CellBases & cellBases(size_t iT) const
Return cell bases for element iT.
Definition ddrcore.hpp:127
const LocalOperators & cellOperators(size_t iT) const
Return cell operators for the cell of index iT.
Definition xrotrot.hpp:65
const size_t & degree() const
Return the polynomial degree.
Definition xrotrot.hpp:52
std::function< double(const Eigen::Vector2d &)> RotType
Definition xrotrot.hpp:23
Eigen::MatrixXd computeL2Product(size_t iT, const double &penalty_factor=1., const IntegralWeight &weight=IntegralWeight(1.)) const
Compute the matrix of the (weighted) L2-product for the cell of index iT.
Definition xrotrot.cpp:237
const DDRCore::EdgeBases & edgeBases(const Edge &E) const
Return edge bases for edge E.
Definition xrotrot.hpp:108
LocalOperators(const Eigen::MatrixXd &_rotor, const Eigen::MatrixXd &_potential)
Definition xrotrot.hpp:28
const DDRCore::CellBases & cellBases(const Cell &T) const
Return cell bases for cell T.
Definition xrotrot.hpp:96
Eigen::MatrixXd cellRotor(const Cell &T) const
Return cell rotor for cell T.
Definition xrotrot.hpp:84
std::function< Eigen::Vector2d(const Eigen::Vector2d &)> FunctionType
Definition xrotrot.hpp:22
const DDRCore::CellBases & cellBases(size_t iT) const
Return cell bases for the cell of index iT.
Definition xrotrot.hpp:90
Eigen::VectorXd interpolate(const FunctionType &v, const RotType &rot_v, const int deg_quad=-1) const
Interpolator of a continuous function.
Definition xrotrot.cpp:55
const EdgeBases & edgeBases(size_t iE) const
Return edge bases for edge iE.
Definition ddrcore.hpp:135
Eigen::MatrixXd potential
Definition xrotrot.hpp:39
Eigen::MatrixXd rotor
Definition xrotrot.hpp:38
std::unique_ptr< PolyBasisCellType > Polyk
Definition ddrcore.hpp:86
bool use_threads
Definition HHO_DiffAdvecReac.hpp:47
Cell * cell(std::size_t index) const
get a constant pointer to a cell using its global index
Definition Mesh2D.hpp:178
std::vector< QuadratureNode > QuadratureRule
Definition quadraturerule.hpp:55
std::unordered_map< VectorZd, double, VecHash > MonomialCellIntegralsType
Type for list of integrals of monomials.
Definition GMpoly_cell.hpp:53
MonomialCellIntegralsType IntegrateCellMonomials(const Cell &T, const size_t maxdeg)
Compute all integrals on a cell of monomials up to a total degree, using vertex values.
Definition GMpoly_cell.cpp:7
Eigen::MatrixXd GramMatrix(const Cell &T, const MonomialScalarBasisCell &basis1, const MonomialScalarBasisCell &basis2, MonomialCellIntegralsType mono_int_map={})
Computes the Gram Matrix of a pair of local scalar monomial bases.
Definition GMpoly_cell.cpp:86
QuadratureRule generate_quadrature_rule(const Cell &T, const int doe, const bool force_split)
Generate quadrature rule on mesh element.
Definition quadraturerule.cpp:10
if(strcmp(field, 'real')) % real valued entries T
Definition mmread.m:93
cols
Definition mmread.m:87
Definition ddr-klplate.hpp:27
static auto v
Definition ddrcore-test.hpp:32
Structure to store element bases.
Definition ddrcore.hpp:81
Structure to store edge bases.
Definition ddrcore.hpp:102
Structure for weights (scalar, at the moment) in integral.
Definition integralweight.hpp:33
Basis dimensions for various polynomial spaces on edges/faces/elements (when relevant): Pk,...
Definition polynomialspacedimension.hpp:55
A structure to store the local operators (scalar rotor and potential)
Definition xrotrot.hpp:27
Evaluate a basis at quadrature nodes. 'BasisFunction' (=Function, Gradient, Curl, Divergence,...
Definition basis.hpp:2284