HArD::Core3D
Hybrid Arbitrary Degree::Core 3D - Library to implement 3D schemes with vertex, edge, face and cell polynomials as unknowns
Loading...
Searching...
No Matches
GMpoly_cell.hpp
Go to the documentation of this file.
1# ifndef _GMPOLY_CELL_HPP
2# define _GMPOLY_CELL_HPP
3
4/*
5
6 Classes to implement the quadrature-free polynomial integration rules
7
8*/
9
10#include <cassert>
11#include <cmath>
12
13#include <algorithm>
14#include <array>
15#include <iostream>
16#include <vector>
17#include <unordered_map>
18
19#include <mesh.hpp>
20#include <quadraturerule.hpp>
21#include <basis.hpp>
22#include <typeinfo>
23
24namespace HArDCore3D {
25
32//----------------------------------------------------------------------
33//----------------------------------------------------------------------
34// INTEGRALS OF MONOMIALS
35//----------------------------------------------------------------------
36//----------------------------------------------------------------------
37
39struct VecHash
40{
41 size_t operator()(const VectorZd & p) const
42 {
43 constexpr size_t b = 100; // max degree must be less than the basis b
44 return p(0) + p(1) * b + p(2) * b*b;
45 }
46};
47
49typedef std::unordered_map<VectorZd, double, VecHash> MonomialCellIntegralsType;
50
52std::vector<MonomialCellIntegralsType> IntegrateCellMonomials_onEdges
53 (const Cell & T,
54 const size_t maxdeg
55 );
56
58std::vector<MonomialCellIntegralsType> IntegrateCellMonomials_onFaces
59 (const Cell & T,
60 const size_t maxdeg,
61 std::vector<MonomialCellIntegralsType> & integrals_edges
62 );
63
66 (const Cell & T,
67 const int maxdeg
68 );
69
72 (const Cell & T,
73 const size_t degree,
75 );
76
77//----------------------------------------------------------------------
78//----------------------------------------------------------------------
79// TRANSFORMATIONS OF GRAM MATRICES FOR DERIVED BASES
80//----------------------------------------------------------------------
81//----------------------------------------------------------------------
82
84template<typename BasisType>
85inline Eigen::MatrixXd transformGM(const Family<BasisType> & family_basis,
86 const char RC,
87 const Eigen::MatrixXd & anc_GM
88 )
89 {
90 if (RC=='R'){
91 return family_basis.matrix() * anc_GM;
92 }else{
93 return anc_GM * (family_basis.matrix()).transpose();
94 }
95 }
96
98template<typename BasisType>
99inline Eigen::MatrixXd transformGM(const RestrictedBasis<BasisType> & restr_basis,
100 const char RC,
101 const Eigen::MatrixXd & anc_GM
102 )
103 {
104 if (RC=='R'){
105 return anc_GM.topRows(restr_basis.dimension());
106 }else{
107 return anc_GM.leftCols(restr_basis.dimension());
108 }
109 }
110
112template<typename BasisType>
113inline Eigen::MatrixXd transformGM(const ShiftedBasis<BasisType> & shifted_basis,
114 const char RC,
115 const Eigen::MatrixXd & anc_GM
116 )
117 {
118 if (RC=='R'){
119 return anc_GM.bottomRows(shifted_basis.dimension());
120 }else{
121 return anc_GM.rightCols(shifted_basis.dimension());
122 }
123 }
124
125
126//----------------------------------------------------------------------
127//----------------------------------------------------------------------
128// FUNCTIONS TO COMPUTE GRAM MATRICES
129//----------------------------------------------------------------------
130//----------------------------------------------------------------------
131
132//
133/* BASIC ONES: Monomial, tensorized, and generic template */
134
136Eigen::MatrixXd GramMatrix(
137 const Cell & T,
138 const MonomialScalarBasisCell & basis1,
139 const MonomialScalarBasisCell & basis2,
141 );
142
144template<typename BasisType>
145Eigen::MatrixXd GramMatrix(const Cell& T, const BasisType & basis, MonomialCellIntegralsType mono_int_map = {})
146 {
147 return GramMatrix(T, basis, basis, mono_int_map);
148 }
149
151template<typename BasisType1, typename BasisType2, size_t N>
152Eigen::MatrixXd GramMatrix(
153 const Cell& T,
157 )
158 {
159 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(basis1.dimension(), basis2.dimension());
160
161 Eigen::MatrixXd anc_gm = GramMatrix(T, basis1.ancestor(), basis2.ancestor(), mono_int_map);
162 size_t dim1 = anc_gm.rows();
163 size_t dim2 = anc_gm.cols();
164
165 for (size_t i=0; i<N; i++){
166 gm.block(i*dim1, i*dim2, dim1, dim2) = anc_gm;
167 }
168 return gm;
169 }
170
171
173Eigen::MatrixXd GramMatrix(
174 const Cell & T,
175 const RolyComplBasisCell & basis1,
176 const RolyComplBasisCell & basis2,
178 );
179
181template<typename BasisType1, size_t N>
182Eigen::MatrixXd GramMatrix(
183 const Cell & T,
187 )
188 {
189 size_t dim1 = rolycompl_basis.dimension();
190 size_t dim2 = tens_family.dimension();
191 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(dim1, dim2);
192
193 // Integrals of monomials
194 size_t totaldegree = rolycompl_basis.max_degree()+tens_family.max_degree();
196
197 for (size_t m=0; m<N; m++){
198 gm.block(0, m*dim2/N, dim1, dim2/N) = GMRolyComplScalar(T, rolycompl_basis, tens_family.ancestor(), m, intmap);
199 }
200 return gm;
201 }
202
204template<typename BasisType1, size_t N>
205Eigen::MatrixXd GramMatrix(
206 const Cell & T,
210 )
211 {
212 return GramMatrix(T, rolycompl_basis, tens_family, mono_int_map).transpose();
213 }
214
216Eigen::MatrixXd GramMatrix(
217 const Cell & T,
218 const GolyComplBasisCell & basis1,
219 const GolyComplBasisCell & basis2,
221 );
222
224template<typename BasisType1, size_t N>
225Eigen::MatrixXd GramMatrix(
226 const Cell & T,
230 )
231 {
232 size_t dim1 = golycompl_basis.dimension();
233 size_t dim2 = tens_family.dimension();
234 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(dim1, dim2);
235
236 // Integrals of monomials
237 size_t totaldegree = golycompl_basis.max_degree()+tens_family.max_degree();
239
240 size_t dim_l1 = golycompl_basis.dimPkmo();
241 size_t dim_l2 = tens_family.ancestor().dimension();
242 gm.block(0, dim_l2, dim_l1, dim_l2) = GMGolyComplScalar(T, golycompl_basis, tens_family.ancestor(), 0, intmap, 2);
243 gm.block(0, 2*dim_l2, dim_l1, dim_l2) = -GMGolyComplScalar(T, golycompl_basis, tens_family.ancestor(), 0, intmap, 1);
244 gm.block(dim_l1, 0, dim_l1, dim_l2) = -GMGolyComplScalar(T, golycompl_basis, tens_family.ancestor(), 1, intmap, 2);
245 gm.block(dim_l1, 2*dim_l2, dim_l1, dim_l2) = GMGolyComplScalar(T, golycompl_basis, tens_family.ancestor(), 1, intmap, 0);
246 gm.block(2*dim_l1, 0, dim1-2*dim_l1, dim_l2) = GMGolyComplScalar(T, golycompl_basis, tens_family.ancestor(), 2, intmap, 1);
247 gm.block(2*dim_l1, dim_l2, dim1-2*dim_l1, dim_l2) = -GMGolyComplScalar(T, golycompl_basis, tens_family.ancestor(), 2, intmap, 0);
248
249 return gm;
250 }
251
253template<typename BasisType1, size_t N>
254Eigen::MatrixXd GramMatrix(
255 const Cell & T,
259 )
260 {
261 return GramMatrix(T, golycompl_basis, tens_family, mono_int_map).transpose();
262 }
263
265Eigen::MatrixXd GMRolyComplScalar(
266 const Cell & T,
267 const RolyComplBasisCell & rolycompl_basis,
268 const MonomialScalarBasisCell & mono_basis,
269 const size_t m,
271 );
272
274template<typename BasisType>
275Eigen::MatrixXd GMRolyComplScalar(
276 const Cell& T,
277 const RolyComplBasisCell & basis1,
278 const BasisType & basis2,
279 const size_t m,
281 )
282 {
283 // If no ancestor is to be used, we shouldn't be in this overload
284 static_assert(BasisType::hasAncestor, "No method to compute this Gram matrix of derivatives");
285 return transformGM(basis2, 'C', GMRolyComplScalar(T, basis1, basis2.ancestor(), m, mono_int_map) );
286 }
287
289Eigen::MatrixXd GMGolyComplScalar(
290 const Cell & T,
291 const GolyComplBasisCell & golycompl_basis,
292 const MonomialScalarBasisCell & mono_basis,
293 const size_t s,
295 const size_t m = 3,
296 const size_t k1 = 3,
297 const size_t k2 = 3
298 );
299
301template<typename BasisType>
302Eigen::MatrixXd GMGolyComplScalar(
303 const Cell& T,
304 const GolyComplBasisCell & basis1,
305 const BasisType & basis2,
306 const size_t s,
308 const size_t m = 3,
309 const size_t k1 = 3,
310 const size_t k2 = 3
311 )
312 {
313 // If no ancestor is to be used, we shouldn't be in this overload
314 static_assert(BasisType::hasAncestor, "No method to compute this Gram matrix of derivatives");
315 return transformGM(basis2, 'C', GMGolyComplScalar(T, basis1, basis2.ancestor(), s, mono_int_map, m, k1, k2) );
316 }
317
319Eigen::MatrixXd GMGolyCompl(
320 const Cell & T,
321 const GolyComplBasisCell & basis1,
322 const GolyComplBasisCell & basis2,
323 const size_t s1,
324 const size_t s2,
326 const size_t m1 = 3,
327 const size_t m2 = 3,
328 const size_t k1 = 3,
329 const size_t k2 = 3
330 );
331
332
334template<typename BasisType>
335constexpr bool useAncestor()
336 {
337 // For a given basis, we only use the ancestor if it has an ancestor and has the same rank as its
338 // ancestor. If it has a different rank than its ancestor, it must be dealt with a specific overload
339
340 if constexpr(BasisType::hasAncestor){
341 return (BasisType::tensorRank == BasisType::AncestorType::tensorRank);
342 } else {
343 return false;
344 }
345 }
346
348template<typename BasisType1, typename BasisType2>
349Eigen::MatrixXd GramMatrix(const Cell& T,
350 const BasisType1 & basis1,
351 const BasisType2 & basis2,
353 )
354 {
355 // If no ancestor is to be used, we shouldn't be in this overload
356 static_assert(useAncestor<BasisType1>() || useAncestor<BasisType2>(), "No method to compute this Gram matrix");
357
358 if constexpr (!useAncestor<BasisType1>() && useAncestor<BasisType2>()) {
359 return transformGM(basis2, 'C', GramMatrix(T, basis1, basis2.ancestor(), mono_int_map) );
360 } else if constexpr (useAncestor<BasisType1>() && !useAncestor<BasisType2>()) {
361 return transformGM(basis1, 'R', GramMatrix(T, basis1.ancestor(), basis2, mono_int_map) );
362 } else {
363 return transformGM(basis1, 'R', transformGM(basis2, 'C', GramMatrix(T, basis1.ancestor(), basis2.ancestor(), mono_int_map) ) );
364 }
365
366 }
367
368//
369/* Gram matrix of scalar basis with one or two derivatives */
370
372Eigen::MatrixXd GMScalarDerivative(
373 const Cell & T,
374 const MonomialScalarBasisCell & basis1,
375 const MonomialScalarBasisCell & basis2,
376 const size_t m,
378 );
379
381Eigen::MatrixXd GMScalarDerivative(
382 const Cell & T,
383 const MonomialScalarBasisCell & basis1,
384 const MonomialScalarBasisCell & basis2,
385 const size_t m,
386 const size_t l,
388 );
389
391template<typename BasisType1, typename BasisType2>
392Eigen::MatrixXd GMScalarDerivative(
393 const Cell& T,
394 const BasisType1 & basis1,
395 const BasisType2 & basis2,
396 const size_t m,
398 )
399 {
400 // If no ancestor is to be used, we shouldn't be in this overload
401 static_assert(BasisType1::hasAncestor || BasisType2::hasAncestor, "No method to compute this Gram matrix of derivatives");
402
403 if constexpr (!BasisType1::hasAncestor && BasisType2::hasAncestor) {
404 return transformGM(basis2, 'C', GMScalarDerivative(T, basis1, basis2.ancestor(), m, mono_int_map) );
405 } else if constexpr (BasisType1::hasAncestor && !BasisType2::hasAncestor) {
406 return transformGM(basis1, 'R', GMScalarDerivative(T, basis1.ancestor(), basis2, m, mono_int_map) );
407 } else {
408 return transformGM(basis1, 'R', transformGM(basis2, 'C', GMScalarDerivative(T, basis1.ancestor(), basis2.ancestor(), m, mono_int_map) ) );
409 }
410 }
411
413template<typename BasisType1, typename BasisType2>
414Eigen::MatrixXd GMScalarDerivative(
415 const Cell& T,
416 const BasisType1 & basis1,
417 const BasisType2 & basis2,
418 const size_t m,
419 const size_t l,
421 )
422 {
423 // If no ancestor is to be used, we shouldn't be in this overload
424 static_assert(BasisType1::hasAncestor || BasisType2::hasAncestor, "No method to compute this Gram matrix of derivatives");
425
426 if constexpr (!BasisType1::hasAncestor && BasisType2::hasAncestor) {
427 return transformGM(basis2, 'C', GMScalarDerivative(T, basis1, basis2.ancestor(), m, l, mono_int_map) );
428 } else if constexpr (BasisType1::hasAncestor && !BasisType2::hasAncestor) {
429 return transformGM(basis1, 'R', GMScalarDerivative(T, basis1.ancestor(), basis2, m, l, mono_int_map) );
430 } else {
431 return transformGM(basis1, 'R', transformGM(basis2, 'C', GMScalarDerivative(T, basis1.ancestor(), basis2.ancestor(), m, l, mono_int_map) ) );
432 }
433
434 }
435
436//
437/* Gram matrices of vector-valued basis with gradient, curl... */
438
440template<typename BasisType1, typename BasisType2, size_t N>
441Eigen::MatrixXd GramMatrix(
442 const Cell& T,
446 )
447 {
448 size_t dim1 = grad_basis.dimension();
449 size_t dim2 = tens_family.dimension();
450 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(dim1, dim2);
451
452 // Integrals of monomials
453 size_t totaldegree = grad_basis.ancestor().max_degree()+tens_family.max_degree()-1;
455
456 for (size_t m=0; m<N; m++){
457 gm.block(0, m*dim2/N, dim1, dim2/N) = GMScalarDerivative(T, grad_basis.ancestor(), tens_family.ancestor(), m, intmap);
458 }
459 return gm/T.diam();
460 }
461
462
464template<typename BasisType1, typename BasisType2, size_t N>
465Eigen::MatrixXd GramMatrix(
466 const Cell& T,
470 )
471 {
472 return GramMatrix(T, grad_basis, tens_family, mono_int_map).transpose();
473 }
474
475
477template<typename BasisType1, typename BasisType2>
478Eigen::MatrixXd GramMatrix(
479 const Cell& T,
483 )
484 {
485 size_t dim1 = grad_basis1.dimension();
486 size_t dim2 = grad_basis2.dimension();
487 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(dim1, dim2);
488
489 // Integrals of monomials
490 size_t totaldegree = grad_basis1.ancestor().max_degree()+grad_basis2.ancestor().max_degree()-2;
492
493 for (size_t m=0; m<3; m++){
494 gm += GMScalarDerivative(T, grad_basis1.ancestor(), grad_basis2.ancestor(), m, m, intmap);
495 }
496 return gm/std::pow(T.diam(), 2);
497 }
498
500template<typename BasisType1, typename BasisType2>
501Eigen::MatrixXd GramMatrix(const Cell& T,
505 )
506 {
507 return GramMatrixCurlCurl(T, basis1.ancestor(), basis2.ancestor(), mono_int_map);
508 }
509
511template<typename BasisType1, typename BasisType2>
512typename boost::disable_if<boost::is_same<BasisType2, MonomialCellIntegralsType>, Eigen::MatrixXd>::type GramMatrix(
513 const Cell& T,
515 const BasisType2 & basis2,
517 )
518 {
519 return GramMatrixCurl(T, basis1.ancestor(), basis2, mono_int_map);
520 }
521
523template<typename BasisType1, typename Basis2>
524Eigen::MatrixXd GramMatrix(
525 const Cell & T,
526 const BasisType1 & basis1,
527 const CurlBasis<Basis2> & basis2,
529 )
530 {
531 return GramMatrixCurl(T, basis2.ancestor(), basis1, mono_int_map).transpose();
532 }
533
535template<typename BasisType1, typename BasisType2, size_t N>
536Eigen::MatrixXd GramMatrixCurlCurl(
537 const Cell& T,
541 )
542 {
543 size_t dim1 = basis1.dimension();
544 size_t dim2 = basis2.dimension();
545 Eigen::MatrixXd gm(dim1, dim2);
546
547 // Integrals of monomials
548 size_t totaldegree = basis1.max_degree()+basis2.max_degree()-2;
550
551 Eigen::MatrixXd GMxx = GMScalarDerivative(T, basis1.ancestor(), basis2.ancestor(), 0, 0, intmap);
552 Eigen::MatrixXd GMyy = GMScalarDerivative(T, basis1.ancestor(), basis2.ancestor(), 1, 1, intmap);
553 Eigen::MatrixXd GMzz = GMScalarDerivative(T, basis1.ancestor(), basis2.ancestor(), 2, 2, intmap);
554
555 gm.block(0, 0, dim1/N, dim2/N) = GMzz + GMyy;
556 gm.block(0, dim2/N, dim1/N, dim2/N) = -GMScalarDerivative(T, basis1.ancestor(), basis2.ancestor(), 1, 0, intmap);
557 gm.block(0, 2*dim2/N, dim1/N, dim2/N) = -GMScalarDerivative(T, basis1.ancestor(), basis2.ancestor(), 2, 0, intmap);
558 gm.block(dim1/N, 0, dim1/N, dim2/N) = -GMScalarDerivative(T, basis1.ancestor(), basis2.ancestor(), 0, 1, intmap);
559 gm.block(dim1/N, dim2/N, dim1/N, dim2/N) = GMzz + GMxx;
560 gm.block(dim1/N, 2*dim2/N, dim1/N, dim2/N) = -GMScalarDerivative(T, basis1.ancestor(), basis2.ancestor(), 2, 1, intmap);
561 gm.block(2*dim1/N, 0, dim1/N, dim2/N) = -GMScalarDerivative(T, basis1.ancestor(), basis2.ancestor(), 0, 2, intmap);
562 gm.block(2*dim1/N, dim2/N, dim1/N, dim2/N) = -GMScalarDerivative(T, basis1.ancestor(), basis2.ancestor(), 1, 2, intmap);
563 gm.block(2*dim1/N, 2*dim2/N, dim1/N, dim2/N) = GMyy + GMxx;
564
565 return gm/std::pow(T.diam(), 2);
566 }
567
569Eigen::MatrixXd GramMatrixCurlCurl(
570 const Cell& T,
571 const GolyComplBasisCell & basis1,
572 const GolyComplBasisCell & basis2,
574 );
575
577template<typename BasisType2, size_t N>
578Eigen::MatrixXd GramMatrixCurlCurl(
579 const Cell& T,
580 const GolyComplBasisCell & basis1,
583 )
584 {
585 size_t dim1 = basis1.dimension();
586 size_t dim2 = basis2.dimension();
587 Eigen::MatrixXd gm(dim1, dim2);
588
589 // Integrals of monomials
590 size_t totaldegree = basis1.max_degree()+basis2.max_degree();
592
593 size_t dim_l1 = basis1.dimPkmo();
594 gm.block(0, 0, dim_l1, dim2/N) = GMGolyComplScalar(T, basis1, basis2.ancestor(), 0, intmap, 1, 0, 2) - GMGolyComplScalar(T, basis1, basis2.ancestor(), 0, intmap, 2, 0, 1);
595 gm.block(0, dim2/N, dim_l1, dim2/N) = GMGolyComplScalar(T, basis1, basis2.ancestor(), 0, intmap, 2, 0, 0) + GMGolyComplScalar(T, basis1, basis2.ancestor(), 0, intmap, 1, 1, 2)
596 + GMGolyComplScalar(T, basis1, basis2.ancestor(), 0, intmap, 2, 2, 2) + 2/T.diam()*GMGolyComplScalar(T, basis1, basis2.ancestor(), 0, intmap, 3, 3, 2);
597 gm.block(0, 2*dim2/N, dim_l1, dim2/N) = -GMGolyComplScalar(T, basis1, basis2.ancestor(), 0, intmap, 1, 0, 0) - GMGolyComplScalar(T, basis1, basis2.ancestor(), 0, intmap, 1, 1, 1)
598 -GMGolyComplScalar(T, basis1, basis2.ancestor(), 0, intmap, 2, 2, 1) - 2/T.diam()*GMGolyComplScalar(T, basis1, basis2.ancestor(), 0, intmap, 3, 3, 1);
599 gm.block(dim_l1, 0, dim_l1, dim2/N) = -GMGolyComplScalar(T, basis1, basis2.ancestor(), 1, intmap, 2, 1, 1) - GMGolyComplScalar(T, basis1, basis2.ancestor(), 1, intmap, 0, 0, 2)
600 -GMGolyComplScalar(T, basis1, basis2.ancestor(), 1, intmap, 2, 2, 2) - 2/T.diam()*GMGolyComplScalar(T, basis1, basis2.ancestor(), 1, intmap, 3, 3, 2);
601 gm.block(dim_l1, dim2/N, dim_l1, dim2/N) = -GMGolyComplScalar(T, basis1, basis2.ancestor(), 1, intmap, 0, 1, 2) + GMGolyComplScalar(T, basis1, basis2.ancestor(), 1, intmap, 2, 1, 0);
602 gm.block(dim_l1, 2*dim2/N, dim_l1, dim2/N) = GMGolyComplScalar(T, basis1, basis2.ancestor(), 1, intmap, 0, 1, 1) + GMGolyComplScalar(T, basis1, basis2.ancestor(), 1, intmap, 0, 0, 0)
603 +GMGolyComplScalar(T, basis1, basis2.ancestor(), 1, intmap, 2, 2, 0) + 2/T.diam()*GMGolyComplScalar(T, basis1, basis2.ancestor(), 1, intmap, 3, 3, 0);
604 gm.block(2*dim_l1, 0, dim1-2*dim_l1, dim2/N) = -GMGolyComplScalar(T, basis1, basis2.ancestor(), 2, intmap, 1, 2, 2) + GMGolyComplScalar(T, basis1, basis2.ancestor(), 2, intmap, 0, 0, 1)
605 +GMGolyComplScalar(T, basis1, basis2.ancestor(), 2, intmap, 1, 1, 1) + 2/T.diam()*GMGolyComplScalar(T, basis1, basis2.ancestor(), 2, intmap, 3, 3, 1);
606 gm.block(2*dim_l1, dim2/N, dim1-2*dim_l1, dim2/N) = -GMGolyComplScalar(T, basis1, basis2.ancestor(), 2, intmap, 0, 2, 2) - GMGolyComplScalar(T, basis1, basis2.ancestor(), 2, intmap, 0, 0, 0)
607 -GMGolyComplScalar(T, basis1, basis2.ancestor(), 2, intmap, 1, 1, 0) - 2/T.diam()*GMGolyComplScalar(T, basis1, basis2.ancestor(), 2, intmap, 3, 3, 0);
608 gm.block(2*dim_l1, 2*dim2/N, dim1-2*dim_l1, dim2/N) = GMGolyComplScalar(T, basis1, basis2.ancestor(), 2, intmap, 0, 2, 1) - GMGolyComplScalar(T, basis1, basis2.ancestor(), 2, intmap, 1, 2, 0);
609
610 return gm;
611 }
612
614template<typename BasisType1, size_t N>
615Eigen::MatrixXd GramMatrixCurlCurl(
616 const Cell& T,
618 const GolyComplBasisCell & basis2,
620 )
621 {
622 return GramMatrixCurlCurl(T, basis2, basis1, mono_int_map).transpose();
623 }
624
626template<typename BasisType1, typename BasisType2>
627Eigen::MatrixXd GramMatrixCurlCurl(
628 const Cell& T,
629 const BasisType1 & basis1,
630 const BasisType2 & basis2,
632 )
633 {
634 // If no ancestor is to be used, we shouldn't be in this overload
635 static_assert(useAncestor<BasisType1>() || useAncestor<BasisType2>(), "No method to compute this Gram matrix");
636
637 if constexpr (!useAncestor<BasisType1>() && useAncestor<BasisType2>()) {
638 return transformGM(basis2, 'C', GramMatrixCurlCurl(T, basis1, basis2.ancestor(), mono_int_map) );
639 } else if constexpr (useAncestor<BasisType1>() && !useAncestor<BasisType2>()) {
640 return transformGM(basis1, 'R', GramMatrixCurlCurl(T, basis1.ancestor(), basis2, mono_int_map) );
641 } else {
642 return transformGM(basis1, 'R', transformGM(basis2, 'C', GramMatrixCurlCurl(T, basis1.ancestor(), basis2.ancestor(), mono_int_map) ) );
643 }
644 }
645
647template<typename BasisType1, typename BasisType2, size_t N>
648Eigen::MatrixXd GramMatrixCurl(
649 const Cell & T,
653 )
654 {
655 size_t dim1 = basis1.dimension();
656 size_t dim2 = basis2.dimension();
657 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(dim1, dim2);
658
659 // Integrals of monomials
660 size_t totaldegree = basis1.max_degree()+basis2.max_degree()-1;
662
663 Eigen::MatrixXd GMx = GMScalarDerivative(T, basis1.ancestor(), basis2.ancestor(), 0, intmap);
664 Eigen::MatrixXd GMy = GMScalarDerivative(T, basis1.ancestor(), basis2.ancestor(), 1, intmap);
665 Eigen::MatrixXd GMz = GMScalarDerivative(T, basis1.ancestor(), basis2.ancestor(), 2, intmap);
666
667 gm.block(0, dim2/N, dim1/N, dim2/N) = GMz;
668 gm.block(0, 2*dim2/N, dim1/N, dim2/N) = -GMy;
669 gm.block(dim1/N, 0, dim1/N, dim2/N) = -GMz;
670 gm.block(dim1/N, 2*dim2/N, dim1/N, dim2/N) = GMx;
671 gm.block(2*dim1/N, 0, dim1/N, dim2/N) = GMy;
672 gm.block(2*dim1/N, dim2/N, dim1/N, dim2/N) = -GMx;
673
674 return gm/T.diam();
675 }
676
678template<typename BasisType2, size_t N>
679Eigen::MatrixXd GramMatrixCurl(
680 const Cell & T,
681 const GolyComplBasisCell & basis1,
684 )
685 {
686 size_t dim1 = basis1.dimension();
687 size_t dim2 = basis2.dimension();
688 Eigen::MatrixXd gm(dim1, dim2);
689
690 // Integrals of monomials
691 size_t totaldegree = basis1.max_degree()+basis2.max_degree();
693
694 size_t dim_l1 = basis1.dimPkmo();
695 gm.block(0, 0, dim_l1, dim2/N) = -GMGolyComplScalar(T, basis1, basis2.ancestor(), 0, intmap, 1, 1)
696 -GMGolyComplScalar(T, basis1, basis2.ancestor(), 0, intmap, 2, 2)
697 -2*GMGolyComplScalar(T, basis1, basis2.ancestor(), 0, intmap)/T.diam();
698 gm.block(0, dim2/N, dim_l1, dim2/N) = GMGolyComplScalar(T, basis1, basis2.ancestor(), 0, intmap, 1, 0);
699 gm.block(0, 2*dim2/N, dim_l1, dim2/N) = GMGolyComplScalar(T, basis1, basis2.ancestor(), 0, intmap, 2, 0);
700 gm.block(dim_l1, 0, dim_l1, dim2/N) = GMGolyComplScalar(T, basis1, basis2.ancestor(), 1, intmap, 0, 1);
701 gm.block(dim_l1, dim2/N, dim_l1, dim2/N) = -GMGolyComplScalar(T, basis1, basis2.ancestor(), 1, intmap, 0, 0)
702 -GMGolyComplScalar(T, basis1, basis2.ancestor(), 1, intmap, 2, 2)
703 -2*GMGolyComplScalar(T, basis1, basis2.ancestor(), 1, intmap)/T.diam();
704 gm.block(dim_l1, 2*dim2/N, dim_l1, dim2/N) = GMGolyComplScalar(T, basis1, basis2.ancestor(), 1, intmap, 2, 1);
705 gm.block(2*dim_l1, 0, dim1-2*dim_l1, dim2/N) = GMGolyComplScalar(T, basis1, basis2.ancestor(), 2, intmap, 0, 2);
706 gm.block(2*dim_l1, dim2/N, dim1-2*dim_l1, dim2/N) = GMGolyComplScalar(T, basis1, basis2.ancestor(), 2, intmap, 1, 2);
707 gm.block(2*dim_l1, 2*dim2/N, dim1-2*dim_l1, dim2/N) = -GMGolyComplScalar(T, basis1, basis2.ancestor(), 2, intmap, 0, 0)
708 -GMGolyComplScalar(T, basis1, basis2.ancestor(), 2, intmap, 1, 1)
709 -2*GMGolyComplScalar(T, basis1, basis2.ancestor(), 2, intmap)/T.diam();
710
711 return gm;
712 }
713
715template<typename BasisType1, typename BasisType2>
716Eigen::MatrixXd GramMatrixCurl(
717 const Cell& T,
718 const BasisType1 & basis1,
719 const BasisType2 & basis2,
721 )
722 {
723 // If no ancestor is to be used, we shouldn't be in this overload
724 static_assert(useAncestor<BasisType1>() || useAncestor<BasisType2>(), "No method to compute this Gram matrix");
725
726 if constexpr (!useAncestor<BasisType1>() && useAncestor<BasisType2>()) {
727 return transformGM(basis2, 'C', GramMatrixCurl(T, basis1, basis2.ancestor(), mono_int_map) );
728 } else if constexpr (useAncestor<BasisType1>() && !useAncestor<BasisType2>()) {
729 return transformGM(basis1, 'R', GramMatrixCurl(T, basis1.ancestor(), basis2, mono_int_map) );
730 } else {
731 return transformGM(basis1, 'R', transformGM(basis2, 'C', GramMatrixCurl(T, basis1.ancestor(), basis2.ancestor(), mono_int_map) ) );
732 }
733 }
734
736template<typename BasisType1, typename BasisType2>
737Eigen::MatrixXd GramMatrixCurl(
738 const Cell& T,
739 const BasisType1 & basis1,
742 )
743 {
744 if constexpr (!useAncestor<BasisType1>()) {
745 return GramMatrixCurlCurl(T, basis1, basis2.ancestor(), mono_int_map);
746 } else {
747 return transformGM(basis1, 'R', GramMatrixCurlCurl(T, basis1.ancestor(), basis2.ancestor(), mono_int_map) );
748 }
749 }
750
752template<typename BasisType1, typename BasisType2>
753Eigen::MatrixXd GramMatrix(const Cell& T,
757 )
758 {
759 return GramMatrixDivDiv(T, basis1.ancestor(), basis2.ancestor(), mono_int_map);
760 }
761
763Eigen::MatrixXd GMRolyComplScalarDiv(
764 const Cell & T,
765 const MonomialScalarBasisCell & mono_basis,
766 const RolyComplBasisCell & rolycompl_basis,
767 const size_t k,
769 );
770
772template<typename BasisType>
773Eigen::MatrixXd GMRolyComplScalarDiv(
774 const Cell& T,
775 const BasisType & basis1,
776 const RolyComplBasisCell & basis2,
777 const size_t k,
779 )
780 {
781 // If no ancestor is to be used, we shouldn't be in this overload
782 static_assert(BasisType::hasAncestor, "No method to compute this Gram matrix of derivatives");
783 return transformGM(basis1, 'R', GMRolyComplScalarDiv(T, basis1.ancestor(), basis2, k, mono_int_map) );
784 }
785
787template<typename BasisType1, typename BasisType2, size_t N>
788Eigen::MatrixXd GramMatrixDivDiv(
789 const Cell& T,
793 )
794 {
795 size_t dim1 = basis1.dimension();
796 size_t dim2 = basis2.dimension();
797 Eigen::MatrixXd gm(dim1, dim2);
798
799 // Integrals of monomials
800 size_t totaldegree = basis1.max_degree()+basis2.max_degree()-2;
802
803 for (size_t i = 0; i < N; i++) {
804 for (size_t j = 0; j < N; j++) {
805 gm.block(i*dim1/N, j*dim2/N, dim1/N, dim2/N) = GMScalarDerivative(T, basis1.ancestor(), basis2.ancestor(), i, j, intmap);
806 }
807 }
808
809 return gm/std::pow(T.diam(), 2);
810 }
811
813Eigen::MatrixXd GramMatrixDivDiv(
814 const Cell& T,
815 const RolyComplBasisCell & basis1,
816 const RolyComplBasisCell & basis2,
818 );
819
821template<typename BasisType2, size_t N>
822Eigen::MatrixXd GramMatrixDivDiv(
823 const Cell& T,
824 const RolyComplBasisCell & basis1,
827 )
828 {
829 return GramMatrixDivDiv(T, basis2, basis1, mono_int_map).transpose();
830 }
831
833template<typename BasisType1, size_t N>
834Eigen::MatrixXd GramMatrixDivDiv(
835 const Cell& T,
837 const RolyComplBasisCell & basis2,
839 )
840 {
841 size_t dim1 = basis1.dimension();
842 size_t dim2 = basis2.dimension();
843 Eigen::MatrixXd gm(dim1, dim2);
844
845 // Integrals of monomials
846 size_t totaldegree = basis1.max_degree()+basis2.max_degree();
848
849 for (size_t i = 0; i < N; i++) {
850 gm.block(i*dim1/N, 0, dim1/N, dim2) = GMRolyComplScalarDiv(T, basis1.ancestor(), basis2, i, mono_int_map);
851 }
852
853 return gm;
854 }
855
857template<typename BasisType1, typename BasisType2>
858Eigen::MatrixXd GramMatrixDivDiv(
859 const Cell& T,
860 const BasisType1 & basis1,
861 const BasisType2 & basis2,
863 )
864 {
865 // If no ancestor is to be used, we shouldn't be in this overload
866 static_assert(useAncestor<BasisType1>() || useAncestor<BasisType2>(), "No method to compute this Gram matrix");
867
868 if constexpr (!useAncestor<BasisType1>() && useAncestor<BasisType2>()) {
869 return transformGM(basis2, 'C', GramMatrixDivDiv(T, basis1, basis2.ancestor(), mono_int_map) );
870 } else if constexpr (useAncestor<BasisType1>() && !useAncestor<BasisType2>()) {
871 return transformGM(basis1, 'R', GramMatrixDivDiv(T, basis1.ancestor(), basis2, mono_int_map) );
872 } else {
873 return transformGM(basis1, 'R', transformGM(basis2, 'C', GramMatrixDivDiv(T, basis1.ancestor(), basis2.ancestor(), mono_int_map) ) );
874 }
875 }
876
878template<typename BasisType1, typename BasisType2>
879typename boost::disable_if<boost::is_same<BasisType2, MonomialCellIntegralsType>, Eigen::MatrixXd>::type GramMatrix(
880 const Cell& T,
882 const BasisType2 & basis2,
884 )
885 {
886 return GramMatrixDiv(T, basis1.ancestor(), basis2, mono_int_map);
887 }
888
890template<typename BasisType1, typename Basis2>
891Eigen::MatrixXd GramMatrix(
892 const Cell & T,
893 const BasisType1 & basis1,
896 )
897 {
898 return GramMatrixDiv(T, basis2.ancestor(), basis1, mono_int_map).transpose();
899 }
900
902template<typename BasisType1, size_t N>
903Eigen::MatrixXd GramMatrixDiv(
904 const Cell & T,
908 )
909 {
910 size_t dim1 = basis1.dimension();
911 size_t dim2 = basis2.dimension();
912 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(dim1, dim2);
913
914 // Integrals of monomials
915 size_t totaldegree = basis1.max_degree()+basis2.max_degree()-1;
917
918 for (size_t i = 0; i < N; i++) {
919 gm.block(i*dim1/N, 0, dim1/N, dim2) = GMScalarDerivative(T, basis1.ancestor(), basis2, i, intmap);
920 }
921
922 return gm/T.diam();
923 }
924
926Eigen::MatrixXd GramMatrixDiv(
927 const Cell & T,
928 const RolyComplBasisCell & basis1,
929 const MonomialScalarBasisCell & basis2,
931 );
932
934template<typename BasisType1, typename BasisType2>
935Eigen::MatrixXd GramMatrixDiv(
936 const Cell& T,
937 const BasisType1 & basis1,
938 const BasisType2 & basis2,
940 )
941 {
942 // If no ancestor is to be used, we shouldn't be in this overload
943 static_assert(useAncestor<BasisType1>() || useAncestor<BasisType2>(), "No method to compute this Gram matrix");
944
945 if constexpr (!useAncestor<BasisType1>() && useAncestor<BasisType2>()) {
946 return transformGM(basis2, 'C', GramMatrixDiv(T, basis1, basis2.ancestor(), mono_int_map) );
947 } else if constexpr (useAncestor<BasisType1>() && !useAncestor<BasisType2>()) {
948 return transformGM(basis1, 'R', GramMatrixDiv(T, basis1.ancestor(), basis2, mono_int_map) );
949 } else {
950 return transformGM(basis1, 'R', transformGM(basis2, 'C', GramMatrixDiv(T, basis1.ancestor(), basis2.ancestor(), mono_int_map) ) );
951 }
952 }
953
955template<typename BasisType1, typename BasisType2>
956Eigen::MatrixXd GramMatrixDiv(
957 const Cell& T,
958 const BasisType1 & basis1,
961 )
962 {
963 if constexpr (!useAncestor<BasisType1>()) {
964 return GramMatrixDivDiv(T, basis1, basis2.ancestor(), mono_int_map);
965 } else {
966 return transformGM(basis1, 'R', GramMatrixDivDiv(T, basis1.ancestor(), basis2.ancestor(), mono_int_map) );
967 }
968 }
969
970/*------------- Templates for MatrixFamily (including Divergence thereof, and vs Gradient<Tensorized> --------------------*/
971
973template<typename BasisType1, typename BasisType2, size_t N>
974Eigen::MatrixXd GramMatrix(
975 const Cell& T,
979 )
980 {
981 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(basis1.dimension(), basis2.dimension());
982
983 Eigen::MatrixXd anc_gm = GramMatrix(T, basis1.ancestor(), basis2.ancestor(), mono_int_map);
984 size_t dim1 = anc_gm.rows();
985 size_t dim2 = anc_gm.cols();
986
987 for (size_t i=0; i<N*N; i++){
988 gm.block(i*dim1, i*dim2, dim1, dim2) = anc_gm;
989 }
990 return gm;
991 }
992
994template<typename BasisType1, typename BasisType2>
995Eigen::MatrixXd GramMatrix(
996 const Cell& T,
1000 )
1001 {
1002 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(basis1.dimension(), basis2.dimension());
1003
1004 // Grab the scalar bases underlying basis1 and basis2
1005 BasisType1 scalar_basis1 = basis1.ancestor().ancestor();
1006 BasisType2 scalar_basis2 = basis2.ancestor();
1007 size_t dim1 = scalar_basis1.dimension();
1008 size_t dim2 = scalar_basis2.dimension();
1009
1010 // Integrals of monomials
1011 size_t totaldegree = scalar_basis1.max_degree() + scalar_basis2.max_degree();
1013
1014 for (size_t j=0; j < dimspace; j++){
1016 for (size_t i=0; i < dimspace; i++){
1017 gm.block(j*dimspace*dim1 + i*dim1, i*dim2, dim1, dim2) = gm_anc;
1018 }
1019 }
1020
1021 return gm/T.diam();
1022 }
1023
1024
1026template<typename BasisType1, typename BasisType2>
1027Eigen::MatrixXd GramMatrix(
1028 const Cell& T,
1032 )
1033 {
1034 return GramMatrix(T, basis2, basis1, mono_int_map).transpose();
1035 }
1036
1037
1039template<typename BasisType1, typename BasisType2>
1040Eigen::MatrixXd GramMatrix(
1041 const Cell& T,
1045 )
1046 {
1047 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(basis1.dimension(), basis2.dimension());
1048
1049 // Grab the scalar bases underlying basis1 and basis2
1050 BasisType1 scalar_basis1 = basis1.ancestor().ancestor();
1051 BasisType2 scalar_basis2 = basis2.ancestor();
1052 size_t dim1 = scalar_basis1.dimension();
1053 size_t dim2 = scalar_basis2.dimension();
1054
1055 // Integrals of monomials
1056 size_t totaldegree = scalar_basis1.max_degree() + scalar_basis2.max_degree();
1058
1059 for (size_t j=0; j < dimspace; j++){
1061 for (size_t i=0; i < dimspace; i++){
1062 gm.block(i*dim1, j*dimspace*dim2 + i*dim2, dim1, dim2) = gm_anc;
1063 }
1064 }
1065
1066 return gm/T.diam();
1067 }
1068
1070template<typename BasisType1, typename BasisType2>
1071Eigen::MatrixXd GramMatrix(
1072 const Cell& T,
1076 )
1077 {
1078 return GramMatrix(T, basis2, basis1, mono_int_map).transpose();
1079 }
1080
1082template<typename BasisType1, typename BasisType2, size_t N>
1083Eigen::MatrixXd GramMatrix(
1084 const Cell& T,
1088 )
1089 {
1090 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(basis1.dimension(), basis2.dimension());
1091
1092 // Grab the scalar bases underlying basis1 and basis2
1093 BasisType1 scalar_basis1 = basis1.ancestor().ancestor();
1094 BasisType2 scalar_basis2 = basis2.ancestor().ancestor();
1095 size_t dim1 = scalar_basis1.dimension();
1096 size_t dim2 = scalar_basis2.dimension();
1097
1098 // Integrals of monomials
1099 size_t totaldegree = scalar_basis1.max_degree() + scalar_basis2.max_degree();
1101
1102 // Gram matrices of sum_i \partial_i phi \partial_i psi for the two scalar bases phi, psi
1103 Eigen::MatrixXd gm_anc = Eigen::MatrixXd::Zero(dim1, dim2);
1104 for (size_t k=0; k < dimspace; k++){
1106 }
1107
1108 for (size_t i=0; i < N; i++){
1109 gm.block(i*dim1, i*dim2, dim1, dim2) = gm_anc;
1110 }
1111
1112 return gm/(std::pow(T.diam(),2));
1113 }
1114
1116} // end of namespace HArDCore3D
1117
1118#endif // end of _GMPOLY_CELL_HPP
Basis for the space of curls of polynomials.
Definition basis.hpp:1318
Basis (or rather family) of divergence of an existing basis.
Definition basis.hpp:1381
Family of functions expressed as linear combination of the functions of a given basis.
Definition basis.hpp:389
Basis for the complement G^{c,k}(T) in P^k(T)^3 of the range of grad.
Definition basis.hpp:1531
Basis for the space of gradients of polynomials.
Definition basis.hpp:1256
Matrix family obtained from a scalar family.
Definition basis.hpp:778
Scalar monomial basis on a cell.
Definition basis.hpp:155
Generate a basis restricted to the first "dimension" functions.
Definition basis.hpp:1147
Basis for the complement R^{c,k}(T) in P^k(T)^3 of the range of curl.
Definition basis.hpp:1460
Generate a basis where the function indices are shifted.
Definition basis.hpp:1040
Vector family obtained by tensorization of a scalar family.
Definition basis.hpp:610
constexpr int dimspace
Dimension, and generic types for vector in correct dimension (makes it easier to translate a code bet...
Definition basis.hpp:50
@ Matrix
Definition basis.hpp:67
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:170
Eigen::MatrixXd GramMatrixDiv(const Cell &T, const TensorizedVectorFamily< BasisType1, N > &basis1, const MonomialScalarBasisCell &basis2, MonomialCellIntegralsType mono_int_map={})
Template to compute the Gram Matrix of a Divergence<Tensorized> basis and a monomial scalar basis.
Definition GMpoly_cell.hpp:903
Eigen::MatrixXd GramMatrixCurlCurl(const Cell &T, const TensorizedVectorFamily< BasisType1, N > &basis1, const TensorizedVectorFamily< BasisType2, N > &basis2, MonomialCellIntegralsType mono_int_map={})
Template to compute the Gram Matrix of the curl of a tensorized basis and the curl of another tensori...
Definition GMpoly_cell.hpp:536
Eigen::MatrixXd GramMatrixDivDiv(const Cell &T, const TensorizedVectorFamily< BasisType1, N > &basis1, const TensorizedVectorFamily< BasisType2, N > &basis2, MonomialCellIntegralsType mono_int_map={})
Template to compute the Gram Matrix of the divergence of a tensorized basis and the divergence of ano...
Definition GMpoly_cell.hpp:788
Eigen::MatrixXd GMScalarDerivative(const Cell &T, const MonomialScalarBasisCell &basis1, const MonomialScalarBasisCell &basis2, const size_t m, MonomialCellIntegralsType mono_int_map={})
Computes the Gram Matrix of a pair of local scalar monomial bases, taking a partial derivative of the...
Definition GMpoly_cell.cpp:244
MonomialCellIntegralsType IntegrateCellMonomials(const Cell &T, const int maxdeg)
Compute all the integrals of a cell's monomials on the cell.
Definition GMpoly_cell.cpp:117
Eigen::MatrixXd GMGolyComplScalar(const Cell &T, const GolyComplBasisCell &golycompl_basis, const MonomialScalarBasisCell &mono_basis, const size_t s, MonomialCellIntegralsType mono_int_map, const size_t m=3, const size_t k1=3, const size_t k2=3)
Computes the Gram Matrix of the sth section of a GolyCompl Basis and a monomial basis.
Definition GMpoly_cell.cpp:321
Eigen::MatrixXd GMRolyComplScalarDiv(const Cell &T, const MonomialScalarBasisCell &mono_basis, const RolyComplBasisCell &rolycompl_basis, const size_t k, MonomialCellIntegralsType mono_int_map)
Gram Matrix of the divergence of a RolyCompl Basis and the kth derivative of a monomial basis.
Definition GMpoly_cell.cpp:506
MonomialCellIntegralsType CheckIntegralsDegree(const Cell &T, const size_t degree, const MonomialCellIntegralsType &mono_int_map={})
Checks if the degree of an existing list of monomial integrals is sufficient, other re-compute and re...
Definition GMpoly_cell.cpp:160
size_t operator()(const VectorZd &p) const
Definition GMpoly_cell.hpp:41
std::vector< MonomialCellIntegralsType > IntegrateCellMonomials_onEdges(const Cell &T, const size_t maxdeg)
Compute all the integrals, on the edges of a cell, of this cell's monomials up to a max degree.
Definition GMpoly_cell.cpp:7
Eigen::MatrixXd GramMatrixCurl(const Cell &T, const TensorizedVectorFamily< BasisType1, N > &basis1, const TensorizedVectorFamily< BasisType2, N > &basis2, MonomialCellIntegralsType mono_int_map={})
Template to compute the Gram Matrix of a Curl<Tensorized> basis and a tensorized scalar basis.
Definition GMpoly_cell.hpp:648
Eigen::MatrixXd GMGolyCompl(const Cell &T, const GolyComplBasisCell &basis1, const GolyComplBasisCell &basis2, const size_t s1, const size_t s2, MonomialCellIntegralsType mono_int_map, const size_t m1=3, const size_t m2=3, const size_t k1=3, const size_t k2=3)
Computes the Gram Matrix of the (optionally k1th derivative of the) s1th section of GolyCompl (option...
Definition GMpoly_cell.cpp:362
Eigen::MatrixXd GMRolyComplScalar(const Cell &T, const RolyComplBasisCell &rolycompl_basis, const MonomialScalarBasisCell &mono_basis, const size_t m, MonomialCellIntegralsType mono_int_map={})
Computes the Gram Matrix of the mth component of a RolyCompl Basis and a monomial basis.
Definition GMpoly_cell.cpp:298
constexpr bool useAncestor()
Determines if the ancestor of a basis will be used to compute a Gram matrix for this basis.
Definition GMpoly_cell.hpp:335
Eigen::MatrixXd transformGM(const Family< BasisType > &family_basis, const char RC, const Eigen::MatrixXd &anc_GM)
Transforms a Gram Matrix from an ancestor to a family basis.
Definition GMpoly_cell.hpp:85
std::unordered_map< VectorZd, double, VecHash > MonomialCellIntegralsType
Type for list of integrals of monomials.
Definition GMpoly_cell.hpp:49
std::vector< MonomialCellIntegralsType > IntegrateCellMonomials_onFaces(const Cell &T, const size_t maxdeg, std::vector< MonomialCellIntegralsType > &integrals_edges)
Compute all the integrals, on the faces of a cell, of this cell's monomials up to a max degree.
Definition GMpoly_cell.cpp:61
Definition ddr-magnetostatics.hpp:41
Hash function for VectorZd type.
Definition GMpoly_cell.hpp:40