HArD::Core2D
Hybrid Arbitrary Degree::Core 2D - Library to implement 2D schemes with edge 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 <cell.hpp>
21//#include <edge.hpp>
22//#include <vertex.hpp>
23#include <quadraturerule.hpp>
24#include <basis.hpp>
25#include <typeinfo>
26
27namespace HArDCore2D {
28
35//----------------------------------------------------------------------
36//----------------------------------------------------------------------
37// INTEGRALS OF MONOMIALS
38//----------------------------------------------------------------------
39//----------------------------------------------------------------------
40
41
43struct VecHash
44{
45 size_t operator()(const VectorZd & p) const
46 {
47 constexpr size_t b = 100; // max degree must be less than the basis b
48 return p(0) + p(1) * b;
49 }
50};
51
53typedef std::unordered_map<VectorZd, double, VecHash> MonomialCellIntegralsType;
54
55
58 (const Cell & T,
59 const size_t maxdeg
60 );
61
64 (const Cell & T,
65 const size_t degree,
66 const MonomialCellIntegralsType & mono_int_map = {}
67 );
68
69//----------------------------------------------------------------------
70//----------------------------------------------------------------------
71// TRANSFORMATIONS OF GRAM MATRICES FOR DERIVED BASES
72//----------------------------------------------------------------------
73//----------------------------------------------------------------------
74
76template<typename BasisType>
77inline Eigen::MatrixXd transformGM(const Family<BasisType> & family_basis,
78 const char RC,
79 const Eigen::MatrixXd & anc_GM
80 )
81 {
82 if (RC=='R'){
83 return family_basis.matrix() * anc_GM;
84 }else{
85 return anc_GM * (family_basis.matrix()).transpose();
86 }
87 }
88
90template<typename BasisType>
91inline Eigen::MatrixXd transformGM(const RestrictedBasis<BasisType> & restr_basis,
92 const char RC,
93 const Eigen::MatrixXd & anc_GM
94 )
95 {
96 if (RC=='R'){
97 return anc_GM.topRows(restr_basis.dimension());
98 }else{
99 return anc_GM.leftCols(restr_basis.dimension());
100 }
101 }
102
104template<typename BasisType>
105inline Eigen::MatrixXd transformGM(const ShiftedBasis<BasisType> & shifted_basis,
106 const char RC,
107 const Eigen::MatrixXd & anc_GM
108 )
109 {
110 if (RC=='R'){
111 return anc_GM.bottomRows(shifted_basis.dimension());
112 }else{
113 return anc_GM.rightCols(shifted_basis.dimension());
114 }
115 }
116
117
118//----------------------------------------------------------------------
119//----------------------------------------------------------------------
120// FUNCTIONS TO COMPUTE GRAM MATRICES
121//----------------------------------------------------------------------
122//----------------------------------------------------------------------
123
124
125/* BASIC ONES: Monomial, tensorized, and generic template */
126
128Eigen::MatrixXd GramMatrix(
129 const Cell & T,
130 const MonomialScalarBasisCell & basis1,
131 const MonomialScalarBasisCell & basis2,
132 MonomialCellIntegralsType mono_int_map = {}
133 );
134
136template<typename BasisType>
137Eigen::MatrixXd GramMatrix(const Cell& T, const BasisType & basis, MonomialCellIntegralsType mono_int_map = {})
138 {
139 return GramMatrix(T, basis, basis, mono_int_map);
140 };
141
143template<typename BasisType1, typename BasisType2, size_t N>
144Eigen::MatrixXd GramMatrix(
145 const Cell& T,
148 MonomialCellIntegralsType mono_int_map = {}
149 )
150 {
151 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(basis1.dimension(), basis2.dimension());
152
153 Eigen::MatrixXd anc_gm = GramMatrix(T, basis1.ancestor(), basis2.ancestor(), mono_int_map);
154 size_t dim1 = anc_gm.rows();
155 size_t dim2 = anc_gm.cols();
156
157 for (size_t i=0; i<N; i++){
158 gm.block(i*dim1, i*dim2, dim1, dim2) = anc_gm;
159 }
160 return gm;
161 };
162
164Eigen::MatrixXd GramMatrix(
165 const Cell & T,
166 const RolyComplBasisCell & basis1,
167 const RolyComplBasisCell & basis2,
168 MonomialCellIntegralsType mono_int_map = {}
169 );
170
172template<typename BasisType1, size_t N>
173Eigen::MatrixXd GramMatrix(
174 const Cell & T,
175 const RolyComplBasisCell & rolycompl_basis,
176 const TensorizedVectorFamily<BasisType1, N> & tens_family,
177 MonomialCellIntegralsType mono_int_map = {}
178 )
179 {
180 size_t dim1 = rolycompl_basis.dimension();
181 size_t dim2 = tens_family.dimension();
182 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(dim1, dim2);
183
184 // Integrals of monomials
185 size_t totaldegree = rolycompl_basis.max_degree()+tens_family.max_degree();
186 MonomialCellIntegralsType intmap = CheckIntegralsDegree(T, totaldegree, mono_int_map);
187
188 for (size_t m=0; m<N; m++){
189 gm.block(0, m*dim2/N, dim1, dim2/N) = GMRolyComplScalar(T, rolycompl_basis, tens_family.ancestor(), m, intmap);
190 }
191 return gm;
192 };
193
195template<typename BasisType1, size_t N>
196Eigen::MatrixXd GramMatrix(
197 const Cell & T,
198 const TensorizedVectorFamily<BasisType1, N> & tens_family,
199 const RolyComplBasisCell & rolycompl_basis,
200 MonomialCellIntegralsType mono_int_map = {}
201 )
202 {
203 return GramMatrix(T, rolycompl_basis, tens_family, mono_int_map).transpose();
204 };
205
207Eigen::MatrixXd GramMatrix(
208 const Cell & T,
209 const GolyComplBasisCell & basis1,
210 const GolyComplBasisCell & basis2,
211 MonomialCellIntegralsType mono_int_map = {}
212 );
213
215Eigen::MatrixXd GMRolyComplScalar(
216 const Cell & T,
217 const RolyComplBasisCell & rolycompl_basis,
218 const MonomialScalarBasisCell & mono_basis,
219 const size_t m,
220 MonomialCellIntegralsType mono_int_map
221 );
222
224template<typename BasisType>
225Eigen::MatrixXd GMRolyComplScalar(
226 const Cell& T,
227 const RolyComplBasisCell & basis1,
228 const BasisType & basis2,
229 const size_t m,
230 MonomialCellIntegralsType mono_int_map
231 )
232 {
233 // If no ancestor is to be used, we shouldn't be in this overload
234 static_assert(BasisType::hasAncestor, "No method to compute this Gram matrix of derivatives");
235 return transformGM(basis2, 'C', GMRolyComplScalar(T, basis1, basis2.ancestor(), m, mono_int_map) );
236 };
237
239template<typename BasisType>
240constexpr bool useAncestor()
241 {
242 // For a given basis, we only use the ancestor if it has an ancestor and has the same rank as its
243 // ancestor. If it has a different rank than its ancestor, it must be dealt with a specific overload
244
245 if constexpr(BasisType::hasAncestor){
246 return (BasisType::tensorRank == BasisType::AncestorType::tensorRank);
247 } else {
248 return false;
249 }
250 };
251
253template<typename BasisType1, typename BasisType2>
254Eigen::MatrixXd GramMatrix(const Cell& T,
255 const BasisType1 & basis1,
256 const BasisType2 & basis2,
257 MonomialCellIntegralsType mono_int_map = {}
258 )
259 {
260 // If no ancestor is to be used, we shouldn't be in this overload
261 static_assert(useAncestor<BasisType1>() || useAncestor<BasisType2>(), "No method to compute this Gram matrix");
262
263 if constexpr (!useAncestor<BasisType1>() && useAncestor<BasisType2>()) {
264 return transformGM(basis2, 'C', GramMatrix(T, basis1, basis2.ancestor(), mono_int_map) );
265 } else if constexpr (useAncestor<BasisType1>() && !useAncestor<BasisType2>()) {
266 return transformGM(basis1, 'R', GramMatrix(T, basis1.ancestor(), basis2, mono_int_map) );
267 } else {
268 return transformGM(basis1, 'R', transformGM(basis2, 'C', GramMatrix(T, basis1.ancestor(), basis2.ancestor(), mono_int_map) ) );
269 }
270
271 };
272
273
274/* Gram matrix of scalar basis with one or two derivatives */
275
277Eigen::MatrixXd GMScalarDerivative(
278 const Cell & T,
279 const MonomialScalarBasisCell & basis1,
280 const MonomialScalarBasisCell & basis2,
281 const size_t m,
282 MonomialCellIntegralsType mono_int_map = {}
283 );
284
286Eigen::MatrixXd GMScalarDerivative(
287 const Cell & T,
288 const MonomialScalarBasisCell & basis1,
289 const MonomialScalarBasisCell & basis2,
290 const size_t m,
291 const size_t l,
292 MonomialCellIntegralsType mono_int_map = {}
293 );
294
296template<typename BasisType1, typename BasisType2>
297Eigen::MatrixXd GMScalarDerivative(
298 const Cell& T,
299 const BasisType1 & basis1,
300 const BasisType2 & basis2,
301 const size_t m,
302 MonomialCellIntegralsType mono_int_map = {}
303 )
304 {
305 // If no ancestor is to be used, we shouldn't be in this overload
306 static_assert(BasisType1::hasAncestor || BasisType2::hasAncestor, "No method to compute this Gram matrix of derivatives");
307
308 if constexpr (!BasisType1::hasAncestor && BasisType2::hasAncestor) {
309 return transformGM(basis2, 'C', GMScalarDerivative(T, basis1, basis2.ancestor(), m, mono_int_map) );
310 } else if constexpr (BasisType1::hasAncestor && !BasisType2::hasAncestor) {
311 return transformGM(basis1, 'R', GMScalarDerivative(T, basis1.ancestor(), basis2, m, mono_int_map) );
312 } else {
313 return transformGM(basis1, 'R', transformGM(basis2, 'C', GMScalarDerivative(T, basis1.ancestor(), basis2.ancestor(), m, mono_int_map) ) );
314 }
315 };
316
318template<typename BasisType1, typename BasisType2>
319Eigen::MatrixXd GMScalarDerivative(
320 const Cell& T,
321 const BasisType1 & basis1,
322 const BasisType2 & basis2,
323 const size_t m,
324 const size_t l,
325 MonomialCellIntegralsType mono_int_map = {}
326 )
327 {
328 // If no ancestor is to be used, we shouldn't be in this overload
329 static_assert(BasisType1::hasAncestor || BasisType2::hasAncestor, "No method to compute this Gram matrix of derivatives");
330
331 if constexpr (!BasisType1::hasAncestor && BasisType2::hasAncestor) {
332 return transformGM(basis2, 'C', GMScalarDerivative(T, basis1, basis2.ancestor(), m, l, mono_int_map) );
333 } else if constexpr (BasisType1::hasAncestor && !BasisType2::hasAncestor) {
334 return transformGM(basis1, 'R', GMScalarDerivative(T, basis1.ancestor(), basis2, m, l, mono_int_map) );
335 } else {
336 return transformGM(basis1, 'R', transformGM(basis2, 'C', GMScalarDerivative(T, basis1.ancestor(), basis2.ancestor(), m, l, mono_int_map) ) );
337 }
338
339 };
340
341
342/* Gram matrices of vector-valued basis with gradient, curl... */
343
345template<typename BasisType1, typename BasisType2, size_t N>
346Eigen::MatrixXd GramMatrix(
347 const Cell& T,
348 const GradientBasis<BasisType1> & grad_basis,
349 const TensorizedVectorFamily<BasisType2, N> & tens_family,
350 MonomialCellIntegralsType mono_int_map = {}
351 )
352 {
353 size_t dim1 = grad_basis.dimension();
354 size_t dim2 = tens_family.dimension();
355 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(dim1, dim2);
356
357 // Integrals of monomials
358 size_t totaldegree = grad_basis.ancestor().max_degree()+tens_family.max_degree()-1;
359 MonomialCellIntegralsType intmap = CheckIntegralsDegree(T, totaldegree, mono_int_map);
360
361 for (size_t m=0; m<N; m++){
362 gm.block(0, m*dim2/N, dim1, dim2/N) = GMScalarDerivative(T, grad_basis.ancestor(), tens_family.ancestor(), m, intmap);
363 }
364 return gm/T.diam();
365 };
366
367
369template<typename BasisType1, typename BasisType2, size_t N>
370Eigen::MatrixXd GramMatrix(
371 const Cell& T,
372 const TensorizedVectorFamily<BasisType1, N> & tens_family,
373 const GradientBasis<BasisType2> & grad_basis,
374 MonomialCellIntegralsType mono_int_map = {}
375 )
376 {
377 return GramMatrix(T, grad_basis, tens_family, mono_int_map).transpose();
378 };
379
380
382template<typename BasisType1, typename BasisType2>
383Eigen::MatrixXd GramMatrix(
384 const Cell& T,
385 const GradientBasis<BasisType1> & grad_basis1,
386 const GradientBasis<BasisType2> & grad_basis2,
387 MonomialCellIntegralsType mono_int_map = {}
388 )
389 {
390 size_t dim1 = grad_basis1.dimension();
391 size_t dim2 = grad_basis2.dimension();
392 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(dim1, dim2);
393
394 // Integrals of monomials
395 size_t totaldegree = grad_basis1.ancestor().max_degree()+grad_basis2.ancestor().max_degree()-2;
396 MonomialCellIntegralsType intmap = CheckIntegralsDegree(T, totaldegree, mono_int_map);
397
398 for (size_t m=0; m<2; m++){
399 gm += GMScalarDerivative(T, grad_basis1.ancestor(), grad_basis2.ancestor(), m, m, intmap);
400 }
401 return gm/std::pow(T.diam(), 2);
402 };
403
404
405
407template<typename BasisType1, typename BasisType2>
408Eigen::MatrixXd GramMatrix(
409 const Cell & T,
410 const CurlBasis<BasisType1> & basis1,
411 const CurlBasis<BasisType2> & basis2,
412 MonomialCellIntegralsType mono_int_map = {}
413 )
414 {
415 // Dimension of the gram matrix
416 size_t dim1 = basis1.dimension();
417 size_t dim2 = basis2.dimension();
418 size_t totaldegree = basis1.ancestor().max_degree()+basis2.ancestor().max_degree()-2;
419 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(dim1,dim2);
420
421 // Obtain integration data from IntegrateCellMonomials
422 MonomialCellIntegralsType intmap = CheckIntegralsDegree(T, totaldegree, mono_int_map);
423
424 for (size_t m=0; m<2; m++){
425 gm += GMScalarDerivative(T, basis1.ancestor(), basis2.ancestor(), m, m, intmap);
426 }
427
428 return gm/std::pow(T.diam(), 2);
429 };
430
431
433template<typename BasisType1, typename BasisType2>
434Eigen::MatrixXd GramMatrix(
435 const Cell& T,
436 const CurlBasis<BasisType1> & curl_basis,
437 const TensorizedVectorFamily<BasisType2, 2> & tens_family,
438 MonomialCellIntegralsType mono_int_map = {}
439 )
440 {
441 size_t dim1 = curl_basis.dimension();
442 size_t dim2 = tens_family.dimension();
443 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(dim1, dim2);
444
445 // Integrals of monomials
446 size_t totaldegree = curl_basis.ancestor().max_degree()+tens_family.max_degree()-1;
447 MonomialCellIntegralsType intmap = CheckIntegralsDegree(T, totaldegree, mono_int_map);
448
449 gm.block(0, 0, dim1, dim2/2) = GMScalarDerivative(T, curl_basis.ancestor(), tens_family.ancestor(), 1, intmap);
450 gm.block(0, dim2/2, dim1, dim2/2) = -GMScalarDerivative(T, curl_basis.ancestor(), tens_family.ancestor(), 0, intmap);
451
452 return gm/T.diam();
453 };
454
455
457template<typename BasisType1, typename BasisType2, size_t N>
458Eigen::MatrixXd GramMatrix(
459 const Cell& T,
460 const TensorizedVectorFamily<BasisType1, N> & tens_family,
461 const CurlBasis<BasisType2> & curl_basis,
462 MonomialCellIntegralsType mono_int_map = {}
463 )
464 {
465 return GramMatrix(T, curl_basis, tens_family, mono_int_map).transpose();
466 };
467
468
470template<typename BasisType1, typename BasisType2>
471typename boost::disable_if<boost::is_same<BasisType2, MonomialCellIntegralsType>, Eigen::MatrixXd>::type GramMatrix(
472 const Cell& T,
473 const DivergenceBasis<BasisType1> & basis1,
474 const BasisType2 & basis2,
475 MonomialCellIntegralsType mono_int_map = {}
476 )
477 {
478 return GramMatrixDiv(T, basis1.ancestor(), basis2, mono_int_map);
479 };
480
482template<typename BasisType1, typename Basis2>
483Eigen::MatrixXd GramMatrix(
484 const Cell & T,
485 const BasisType1 & basis1,
486 const DivergenceBasis<Basis2> & basis2,
487 MonomialCellIntegralsType mono_int_map = {}
488 )
489 {
490 return GramMatrixDiv(T, basis2.ancestor(), basis1, mono_int_map).transpose();
491 };
492
494template<typename BasisType1>
495Eigen::MatrixXd GramMatrixDiv(
496 const Cell & T,
498 const MonomialScalarBasisCell & basis2,
499 MonomialCellIntegralsType mono_int_map = {}
500 )
501 {
502 size_t dim1 = basis1.dimension();
503 size_t dim2 = basis2.dimension();
504 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(dim1, dim2);
505
506 // Integrals of monomials
507 size_t totaldegree = basis1.max_degree()+basis2.max_degree()-1;
508 MonomialCellIntegralsType intmap = CheckIntegralsDegree(T, totaldegree, mono_int_map);
509
510 for (size_t i = 0; i < 2; i++) {
511 gm.block(i*dim1/2, 0, dim1/2, dim2) = GMScalarDerivative(T, basis1.ancestor(), basis2, i, intmap);
512 }
513
514 return gm/T.diam();
515 };
516
518Eigen::MatrixXd GramMatrixDiv(
519 const Cell & T,
520 const RolyComplBasisCell & basis1,
521 const MonomialScalarBasisCell & basis2,
522 MonomialCellIntegralsType mono_int_map = {}
523 );
524
526template<typename BasisType1, typename BasisType2>
527Eigen::MatrixXd GramMatrixDiv(
528 const Cell& T,
529 const BasisType1 & basis1,
530 const BasisType2 & basis2,
531 MonomialCellIntegralsType mono_int_map = {}
532 )
533 {
534 // If no ancestor is to be used, we shouldn't be in this overload
535 static_assert(useAncestor<BasisType1>() || useAncestor<BasisType2>(), "No method to compute this Gram matrix");
536
537 if constexpr (!useAncestor<BasisType1>() && useAncestor<BasisType2>()) {
538 return transformGM(basis2, 'C', GramMatrixDiv(T, basis1, basis2.ancestor(), mono_int_map) );
539 } else if constexpr (useAncestor<BasisType1>() && !useAncestor<BasisType2>()) {
540 return transformGM(basis1, 'R', GramMatrixDiv(T, basis1.ancestor(), basis2, mono_int_map) );
541 } else {
542 return transformGM(basis1, 'R', transformGM(basis2, 'C', GramMatrixDiv(T, basis1.ancestor(), basis2.ancestor(), mono_int_map) ) );
543 }
544 };
545
546/*------------- Templates for MatrixFamily --------------------*/
547
549 template<typename BasisType1, typename BasisType2, size_t N>
550 Eigen::MatrixXd GramMatrix(
551 const Cell& T,
552 const MatrixFamily<BasisType1, N> & basis1,
553 const MatrixFamily<BasisType2, N> & basis2,
554 MonomialCellIntegralsType mono_int_map = {}
555 )
556 {
557 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(basis1.dimension(), basis2.dimension());
558
559 Eigen::MatrixXd anc_gm = GramMatrix(T, basis1.ancestor(), basis2.ancestor(), mono_int_map);
560 size_t dim1 = anc_gm.rows();
561 size_t dim2 = anc_gm.cols();
562
563 for (size_t i=0; i<N*N; i++){
564 gm.block(i*dim1, i*dim2, dim1, dim2) = anc_gm;
565 }
566 return gm;
567 }
568
570template<typename BasisType1, typename BasisType2>
571Eigen::MatrixXd GramMatrix(
572 const Cell& T,
575 MonomialCellIntegralsType mono_int_map = {}
576 )
577 {
578 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(basis1.dimension(), basis2.dimension());
579
580 // Grab the scalar bases underlying basis1 and basis2
581 BasisType1 scalar_basis1 = basis1.ancestor().ancestor();
582 BasisType2 scalar_basis2 = basis2.ancestor();
583 size_t dim1 = scalar_basis1.dimension();
584 size_t dim2 = scalar_basis2.dimension();
585
586 // Integrals of monomials
587 size_t totaldegree = scalar_basis1.max_degree() + scalar_basis2.max_degree();
588 MonomialCellIntegralsType intmap = CheckIntegralsDegree(T, totaldegree, mono_int_map);
589
590 for (size_t j=0; j < dimspace; j++){
591 Eigen::MatrixXd gm_anc = GMScalarDerivative(T, scalar_basis1, scalar_basis2, j, intmap);
592 for (size_t i=0; i < dimspace; i++){
593 gm.block(j*dimspace*dim1 + i*dim1, i*dim2, dim1, dim2) = gm_anc;
594 }
595 }
596
597 return gm/T.diam();
598 }
599
601 template<typename BasisType1, typename BasisType2>
602 Eigen::MatrixXd GramMatrix(
603 const Cell& T,
606 MonomialCellIntegralsType mono_int_map = {}
607 )
608 {
609 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(basis1.dimension(), basis2.dimension());
610
611 // Grab the scalar bases underlying basis1 and basis2
612 BasisType1 scalar_basis1 = basis1.ancestor().ancestor();
613 BasisType2 scalar_basis2 = basis2.ancestor();
614 size_t dim1 = scalar_basis1.dimension();
615 size_t dim2 = scalar_basis2.dimension();
616
617 // Integrals of monomials
618 size_t totaldegree = scalar_basis1.max_degree() + scalar_basis2.max_degree();
619 MonomialCellIntegralsType intmap = CheckIntegralsDegree(T, totaldegree, mono_int_map);
620
621 for (size_t j=0; j < dimspace; j++){
622 Eigen::MatrixXd gm_anc = GMScalarDerivative(T, scalar_basis1, scalar_basis2, j, intmap);
623 for (size_t i=0; i < dimspace; i++){
624 gm.block(i*dim1, j*dimspace*dim2 + i*dim2, dim1, dim2) = gm_anc;
625 }
626 }
627
628 return gm/T.diam();
629 }
630
632 template<typename BasisType1, typename BasisType2>
633 Eigen::MatrixXd GramMatrix(
634 const Cell& T,
637 MonomialCellIntegralsType mono_int_map = {}
638 )
639 {
640 return GramMatrix(T, basis2, basis1, mono_int_map).transpose();
641 }
642
644 template<typename BasisType1, typename BasisType2, size_t N>
645 Eigen::MatrixXd GramMatrix(
646 const Cell& T,
649 MonomialCellIntegralsType mono_int_map = {}
650 )
651 {
652 Eigen::MatrixXd gm = Eigen::MatrixXd::Zero(basis1.dimension(), basis2.dimension());
653
654 // Grab the scalar bases underlying basis1 and basis2
655 BasisType1 scalar_basis1 = basis1.ancestor().ancestor();
656 BasisType2 scalar_basis2 = basis2.ancestor().ancestor();
657 size_t dim1 = scalar_basis1.dimension();
658 size_t dim2 = scalar_basis2.dimension();
659
660 // Integrals of monomials
661 size_t totaldegree = scalar_basis1.max_degree() + scalar_basis2.max_degree();
662 MonomialCellIntegralsType intmap = CheckIntegralsDegree(T, totaldegree, mono_int_map);
663
664 // Gram matrices of sum_i \partial_i phi \partial_i psi for the two scalar bases phi, psi
665 Eigen::MatrixXd gm_anc = Eigen::MatrixXd::Zero(dim1, dim2);
666 for (size_t k=0; k < dimspace; k++){
667 gm_anc += GMScalarDerivative(T, scalar_basis1, scalar_basis2, k, k, intmap);
668 }
669
670 for (size_t i=0; i < N; i++){
671 gm.block(i*dim1, i*dim2, dim1, dim2) = gm_anc;
672 }
673
674 return gm/(std::pow(T.diam(),2));
675 }
676
677
679} // end of namespace HArDCore2D
680
681#endif // end of _GMPOLY_CELL_HPP
Basis for the space of curls (vectorial rot) of polynomials.
Definition basis.hpp:1243
Basis (or rather family) of divergence of an existing basis.
Definition basis.hpp:1306
Definition basis.hpp:311
Basis for the space of gradients of polynomials.
Definition basis.hpp:1181
Matrix family obtained from a scalar family.
Definition basis.hpp:719
Scalar monomial basis on a cell.
Definition basis.hpp:166
Generate a basis restricted to the first "dimension" functions.
Definition basis.hpp:1071
Basis for the complement R^{c,k}(T) in P^k(T)^2 of the range of the vectorial rotational on a face.
Definition basis.hpp:1493
Generate a basis where the function indices are shifted.
Definition basis.hpp:961
Vector family obtained by tensorization of a scalar family.
Definition basis.hpp:559
Compute max and min eigenvalues of all matrices for i
Definition compute_eigs.m:5
size_t dimension() const
Compute the dimension of the basis.
Definition basis.hpp:1215
size_t dimension() const
Return the dimension of the family.
Definition basis.hpp:767
Eigen::Vector2i VectorZd
Definition basis.hpp:56
constexpr const ScalarFamilyType & ancestor() const
Return the ancestor (family that has been tensorized)
Definition basis.hpp:689
constexpr const BasisType & ancestor() const
Return the ancestor (basis that the gradient was taken of)
Definition basis.hpp:1227
size_t dimension() const
Return the dimension of the basis.
Definition basis.hpp:1107
size_t max_degree() const
Returns the maximum degree of the basis functions.
Definition basis.hpp:695
size_t dimension() const
Compute the dimension of the basis.
Definition basis.hpp:1520
size_t dimension() const
Return the dimension of the basis.
Definition basis.hpp:995
size_t dimension() const
Compute the dimension of the basis.
Definition basis.hpp:193
size_t max_degree() const
Returns the maximum degree of the basis functions.
Definition basis.hpp:211
constexpr int dimspace
Dimension, and generic types for vector in correct dimension (makes it easier to translate a code bet...
Definition basis.hpp:53
constexpr const BasisType & ancestor() const
Return the ancestor (basis that the gradient was taken of)
Definition basis.hpp:1288
constexpr const BasisType & ancestor() const
Return the ancestor (basis that the gradient was taken of)
Definition basis.hpp:1350
size_t dimension() const
Compute the dimension of the basis.
Definition basis.hpp:1276
size_t dimension() const
Return the dimension of the family.
Definition basis.hpp:595
const ScalarFamilyType & ancestor() const
Return the ancestor (family that has been tensorized)
Definition basis.hpp:827
size_t max_degree() const
Returns the maximum degree of the basis functions.
Definition basis.hpp:1532
const Eigen::MatrixXd & matrix() const
Return the coefficient matrix.
Definition basis.hpp:508
std::unordered_map< VectorZd, double, VecHash > MonomialCellIntegralsType
Type for list of integrals of monomials.
Definition GMpoly_cell.hpp:53
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:240
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:76
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:139
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:77
size_t operator()(const VectorZd &p) const
Definition GMpoly_cell.hpp:45
Eigen::MatrixXd GramMatrixDiv(const Cell &T, const TensorizedVectorFamily< BasisType1, 2 > &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:495
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:193
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
if(strcmp(field, 'real')) % real valued entries T
Definition mmread.m:93
for j
Definition mmread.m:174
Definition ddr-klplate.hpp:27
Hash function for VectorZd type.
Definition GMpoly_cell.hpp:44