ug4
Loading...
Searching...
No Matches
lagrange.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3 * Author: Andreas Vogel
4 *
5 * This file is part of UG4.
6 *
7 * UG4 is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License version 3 (as published by the
9 * Free Software Foundation) with the following additional attribution
10 * requirements (according to LGPL/GPL v3 §7):
11 *
12 * (1) The following notice must be displayed in the Appropriate Legal Notices
13 * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 *
15 * (2) The following notice must be displayed at a prominent place in the
16 * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 *
18 * (3) The following bibliography is recommended for citation and must be
19 * preserved in all covered files:
20 * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 * parallel geometric multigrid solver on hierarchically distributed grids.
22 * Computing and visualization in science 16, 4 (2013), 151-164"
23 * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 * flexible software system for simulating pde based models on high performance
25 * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 *
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU Lesser General Public License for more details.
31 */
32
33#ifndef __H__UG__LIB_DISC__LOCAL_SHAPE_FUNCTION_SET__LAGRANGE__LAGRANGE__
34#define __H__UG__LIB_DISC__LOCAL_SHAPE_FUNCTION_SET__LAGRANGE__LAGRANGE__
35
36#include "../common/lagrange1d.h"
37#include "../local_finite_element_provider.h"
38#include "../local_dof_set.h"
39#include "lagrange_local_dof.h"
43
44namespace ug{
45
47template <typename TRefElem, int TOrder>
49
51template <typename TRefElem>
53
54
56// Vertex
58
60
64template <int TOrder>
66 : public LagrangeLDS<ReferenceVertex>,
67 public BaseLSFS<LagrangeLSFS<ReferenceVertex, TOrder>, 0>
68{
69 private:
71 static const size_t p = TOrder;
72
75
76 public:
79
82
83 public:
85 static const size_t order = TOrder;
86
88 static const int dim = ReferenceVertex::dim;
89
91 static const size_t nsh = 1;
92
93 public:
96
98 inline bool continuous() const {return true;}
99
101 inline size_t num_sh() const {return nsh;}
102
104 inline bool position(size_t i, MathVector<dim>& pos) const
105 {
106 return true;
107 }
108
110 inline shape_type shape(size_t i, const MathVector<dim>& x) const
111 {
112 return 1.0;
113 }
114
116 inline void grad(grad_type& g, size_t i, const MathVector<dim>& x) const
117 {
118 }
119};
120
122
125template <>
127 : public LagrangeLDS<ReferenceVertex>,
128 public BaseLSFS<FlexLagrangeLSFS<ReferenceVertex>, 0>
129{
130 public:
132 static const int dim = ReferenceVertex::dim;
133
134 public:
137
139 FlexLagrangeLSFS(size_t order) {p = order;}
140
142 inline bool continuous() const {return true;}
143
145 inline size_t num_sh() const {return nsh;}
146
148 inline bool position(size_t i, MathVector<dim>& pos) const
149 {
150 return true;
151 }
152
154 inline shape_type shape(size_t i, const MathVector<dim>& x) const
155 {
156 return 1.0;
157 }
158
160 inline void grad(grad_type& g, size_t i, const MathVector<dim>& x) const
161 {
162 }
163
164 protected:
166 size_t p;
167
169 static const size_t nsh = 1;
170};
171
173// Edge
175
177
181template <int TOrder>
183 : public LagrangeLDS<ReferenceEdge>,
184 public BaseLSFS<LagrangeLSFS<ReferenceEdge, TOrder>, 1>
185{
186 private:
188 static const size_t p = TOrder;
189
192
193 public:
196
199
200 public:
202 static const size_t order = TOrder;
203
205 static const int dim = ReferenceEdge::dim;
206
208 static const size_t nsh = p+1;
209
210 public:
212 LagrangeLSFS();
213
215 inline bool continuous() const {return true;}
216
218 inline size_t num_sh() const {return nsh;}
219
221 inline bool position(size_t i, MathVector<dim>& pos) const
222 {
223 pos = EquidistantLagrange1D::position(multi_index(i)[0], p);
224 return true;
225 }
226
228 inline shape_type shape(size_t i, const MathVector<dim>& x) const
229 {
230 return m_vPolynom[multi_index(i)[0]].value(x[0]);
231 }
232
234 inline void grad(grad_type& g, size_t i, const MathVector<dim>& x) const
235 {
236 g[0] = m_vDPolynom[multi_index(i)[0]].value(x[0]);
237 }
238
240 inline const MathVector<dim,int>& multi_index(size_t i) const
241 {
242 check_index(i);
243 return m_vMultiIndex[i];
244 }
245
247 inline size_t index(const MathVector<dim,int>& ind) const
248 {
249 check_multi_index(ind);
250 for(size_t i=0; i<nsh; ++i)
251 if(multi_index(i) == ind) return i;
252 UG_THROW("Index not found in LagrangeLSFS");
253 }
254
257 {
258 check_index(i);
259 return MathVector<1,int>(i);
260 }
261
263 inline size_t mapped_index(const MathVector<dim,int>& ind) const
264 {
265 check_multi_index(ind);
266 return ind[0];
267 }
268
270 inline void check_index(size_t i) const
271 {
272 UG_ASSERT(i < nsh, "Wrong index.");
273 }
274
276 inline void check_multi_index(const MathVector<dim,int>& ind) const
277 {
278 UG_ASSERT(ind[0] < (int)nsh && ind[0] >= 0, "Wrong MultiIndex");
279 }
280
281 protected:
282 Polynomial1D m_vPolynom[p+1];
283 Polynomial1D m_vDPolynom[p+1];
284
285 MathVector<dim,int> m_vMultiIndex[nsh];
286};
287
289
292template <>
294 : public LagrangeLDS<ReferenceEdge>,
295 public BaseLSFS<FlexLagrangeLSFS<ReferenceEdge>, 1>
296{
297 public:
299 static const int dim = ReferenceEdge::dim;
300
301 public:
303 FlexLagrangeLSFS() {set_order(1);}
304
306 FlexLagrangeLSFS(size_t order) {set_order(order);}
307
309 void set_order(size_t order);
310
312 inline bool continuous() const {return true;}
313
315 inline size_t num_sh() const {return nsh;}
316
318 inline bool position(size_t i, MathVector<dim>& pos) const
319 {
320 pos = EquidistantLagrange1D::position(multi_index(i)[0], p);
321 return true;
322 }
323
325 inline shape_type shape(size_t i, const MathVector<dim>& x) const
326 {
327 return m_vPolynom[multi_index(i)[0]].value(x[0]);
328 }
329
331 inline void grad(grad_type& g, size_t i, const MathVector<dim>& x) const
332 {
333 g[0] = m_vDPolynom[multi_index(i)[0]].value(x[0]);
334 }
335
337 inline const MathVector<dim,int>& multi_index(size_t i) const
338 {
339 check_index(i);
340 return m_vMultiIndex[i];
341 }
342
344 inline size_t index(const MathVector<dim,int>& ind) const
345 {
346 check_multi_index(ind);
347 for(size_t i=0; i<nsh; ++i)
348 if(multi_index(i) == ind) return i;
349 UG_THROW("Index not found in LagrangeLSFS");
350 }
351
354 {
355 check_index(i);
356 return MathVector<1,int>(i);
357 }
358
360 inline size_t mapped_index(const MathVector<dim,int>& ind) const
361 {
362 check_multi_index(ind);
363 return ind[0];
364 }
365
367 inline void check_index(size_t i) const
368 {
369 UG_ASSERT(i < nsh, "Wrong index.");
370 }
371
373 inline void check_multi_index(const MathVector<dim,int>& ind) const
374 {
375 UG_ASSERT(ind[0] < (int)nsh && ind[0] >= 0, "Wrong MultiIndex");
376 }
377
378 protected:
380 size_t p;
381
383 size_t nsh;
384
385 std::vector<Polynomial1D> m_vPolynom;
386 std::vector<Polynomial1D> m_vDPolynom;
387
388 std::vector<MathVector<dim,int> > m_vMultiIndex;
389};
390
392// Triangle
394
395template <int TOrder>
397 : public LagrangeLDS<ReferenceTriangle>,
398 public BaseLSFS<LagrangeLSFS<ReferenceTriangle, TOrder>, 2>
399{
400 private:
402 static const size_t p = TOrder;
403
406
407 public:
410
413
414 public:
416 static const size_t order = TOrder;
417
419 static const int dim = ReferenceTriangle::dim;
420
422 static const size_t nsh = BinomialCoefficient<dim + p, p>::value;
423
424 public:
426 LagrangeLSFS();
427
429 inline bool continuous() const {return true;}
430
432 inline size_t num_sh() const {return nsh;}
433
435 inline bool position(size_t i, MathVector<dim>& pos) const
436 {
437 // get Multi Index
438 MathVector<dim,int> ind = multi_index(i);
439
440 // set position
441 for(int d = 0; d < dim; ++d)
443
444 return true;
445 }
446
448 inline number shape(const size_t i, const MathVector<dim>& x) const
449 {
450 // forward
451 return shape(multi_index(i), x);
452 }
453
455 inline number shape(const MathVector<dim,int>& ind, const MathVector<dim>& x) const
456 {
457 check_multi_index(ind);
458 //ReferenceTriangle::check_position(x);
459
460 // get adjoint barycentric index
461 const size_t i0 = p - ind[0] - ind[1];
462 const number x0 = 1.0 - x[0] - x[1];
463
464 return m_vPolynom[ ind[0] ].value(x[0])
465 * m_vPolynom[ ind[1] ].value(x[1])
466 * m_vPolynom[ i0 ].value(x0);
467 }
468
469
471 inline void grad(grad_type& g, const size_t i, const MathVector<dim>& x) const
472 {
473 grad(g, multi_index(i), x);
474 }
475
477 inline void grad(grad_type& g, const MathVector<dim,int> ind,
478 const MathVector<dim>& x) const
479 {
480 check_multi_index(ind);
481 //ReferenceTriangle::check_position(x);
482
483 // get adjoint barycentric index and position
484 const size_t i0 = p - ind[0] - ind[1];
485 const number x0 = 1.0 - x[0] - x[1];
486
487 UG_ASSERT(i0 <= (int)p, "Wrong Multiindex.");
488 UG_ASSERT(x0 <= 1.0+SMALL && x0 >= -SMALL, "Wrong Position.");
489
490 // loop dimensions
491 for(int d = 0; d < dim; ++d)
492 {
493 g[d] = m_vDPolynom[ind[d]].value(x[d])
494 * m_vPolynom[i0].value(x0);
495 g[d] += (-1) * m_vDPolynom[i0].value(x0)
496 * m_vPolynom[ind[d]].value(x[d]);
497
498 // multiply by all functions not depending on x[d]
499 for(int d2 = 0; d2 < dim; ++d2)
500 {
501 // skip own value
502 if(d2 == d) continue;
503
504 g[d] *= m_vPolynom[ind[d2]].value(x[d2]);
505 }
506 }
507 }
508
510 inline const MathVector<dim,int>& multi_index(size_t i) const
511 {
512 check_index(i);
513 return m_vMultiIndex[i];
514 }
515
517 inline size_t index(const MathVector<dim,int>& ind) const
518 {
519 check_multi_index(ind);
520 for(size_t i=0; i<nsh; ++i)
521 if(multi_index(i) == ind) return i;
522 UG_THROW("Index not found in LagrangeLSFS");
523 }
524
526 inline size_t mapped_index(const MathVector<dim,int>& ind) const
527 {
528 check_multi_index(ind);
529
530 size_t res = ind[0];
531 for(int i = 0; i < ind[1]; ++i)
532 res += (p+1-i);
533
534 check_index(res);
535 return res;
536 }
537
540 {
541 check_index(i);
542
543 int i0 = i, i1;
544 for(i1 = 0; i1 < (int)p; ++i1)
545 {
546 const int diff = i0 - (p+1-i1);
547 if(diff < 0) break;
548 i0 = diff;
549 }
550
551 UG_ASSERT(i0 >= 0, "i0 is negative ("<<i0<<")");
552 UG_ASSERT(i1 >= 0, "i1 is negative ("<<i1<<")");
553 return MathVector<dim,int>( i0, i1 );
554 }
555
557 inline void check_index(size_t i) const
558 {
559 UG_ASSERT(i < nsh, "Wrong index.");
560 }
561
563 inline void check_multi_index(const MathVector<dim,int>& ind) const
564 {
565 UG_ASSERT(ind[0] <= (int)p && ind[0]>=0, "Wrong Multiindex.");
566 UG_ASSERT(ind[1] <= (int)p && ind[0]>=0, "Wrong Multiindex.");
567 UG_ASSERT(ind[0] + ind[1] <= (int)p && ind[0]>=0, "Wrong Multiindex.");
568 }
569
570 private:
571 Polynomial1D m_vPolynom[p+1];
572 Polynomial1D m_vDPolynom[p+1];
573
574 MathVector<dim,int> m_vMultiIndex[nsh];
575};
576
577
578template <>
580 : public LagrangeLDS<ReferenceTriangle>,
581 public BaseLSFS<FlexLagrangeLSFS<ReferenceTriangle>, 2>
582{
583 public:
585 static const int dim = ReferenceTriangle::dim;
586
587 public:
589 FlexLagrangeLSFS() {set_order(1);}
590
592 FlexLagrangeLSFS(size_t order) {set_order(order);}
593
595 void set_order(size_t order);
596
598 inline bool continuous() const {return true;}
599
601 inline size_t num_sh() const {return nsh;}
602
604 inline bool position(size_t i, MathVector<dim>& pos) const
605 {
606 // get Multi Index
607 MathVector<dim,int> ind = multi_index(i);
608
609 // set position
610 for(int d = 0; d < dim; ++d)
612
613 return true;
614 }
615
617 inline number shape(const size_t i, const MathVector<dim>& x) const
618 {
619 // forward
620 return shape(multi_index(i), x);
621 }
622
624 inline number shape(const MathVector<dim,int>& ind, const MathVector<dim>& x) const
625 {
626 check_multi_index(ind);
627 //ReferenceTriangle::check_position(x);
628
629 // get adjoint barycentric index
630 const size_t i0 = p - ind[0] - ind[1];
631 const number x0 = 1.0 - x[0] - x[1];
632
633 return m_vPolynom[ ind[0] ].value(x[0])
634 * m_vPolynom[ ind[1] ].value(x[1])
635 * m_vPolynom[ i0 ].value(x0);
636 }
637
638
640 inline void grad(grad_type& g, const size_t i, const MathVector<dim>& x) const
641 {
642 grad(g, multi_index(i), x);
643 }
644
646 inline void grad(grad_type& g, const MathVector<dim,int> ind,
647 const MathVector<dim>& x) const
648 {
649 check_multi_index(ind);
650 //ReferenceTriangle::check_position(x);
651
652 // get adjoint barycentric index and position
653 const int i0 = p - ind[0] - ind[1];
654 const number x0 = 1.0 - x[0] - x[1];
655
656 UG_ASSERT(i0 <= (int)p && i0 >= 0, "Wrong Multiindex.");
657 UG_ASSERT(x0 <= 1.0+SMALL && x0 >= -SMALL, "Wrong Position.");
658
659 // loop dimensions
660 for(int d = 0; d < dim; ++d)
661 {
662 g[d] = m_vDPolynom[ind[d]].value(x[d])
663 * m_vPolynom[i0].value(x0);
664 g[d] += (-1) * m_vDPolynom[i0].value(x0)
665 * m_vPolynom[ind[d]].value(x[d]);
666
667 // multiply by all functions not depending on x[d]
668 for(int d2 = 0; d2 < dim; ++d2)
669 {
670 // skip own value
671 if(d2 == d) continue;
672
673 g[d] *= m_vPolynom[ind[d2]].value(x[d2]);
674 }
675 }
676 }
677
679 inline const MathVector<dim,int>& multi_index(size_t i) const
680 {
681 check_index(i);
682 return m_vMultiIndex[i];
683 }
684
686 inline size_t index(const MathVector<dim,int>& ind) const
687 {
688 check_multi_index(ind);
689 for(size_t i=0; i<nsh; ++i)
690 if(multi_index(i) == ind) return i;
691 UG_THROW("Index not found in LagrangeLSFS");
692 }
693
695 inline size_t mapped_index(const MathVector<dim,int>& ind) const
696 {
697 check_multi_index(ind);
698
699 size_t res = ind[0];
700 for(int i = 0; i < ind[1]; ++i)
701 res += (p+1-i);
702
703 check_index(res);
704 return res;
705 }
706
709 {
710 check_index(i);
711
712 int i0 = i, i1;
713 for(i1 = 0; i1 < (int)p; ++i1)
714 {
715 const int diff = i0 - (p+1-i1);
716 if(diff < 0) break;
717 i0 = diff;
718 }
719
720 UG_ASSERT(i0 >= 0, "i0 is negative ("<<i0<<")");
721 UG_ASSERT(i1 >= 0, "i1 is negative ("<<i1<<")");
722 return MathVector<dim,int>( i0, i1 );
723 }
724
726 inline void check_index(size_t i) const
727 {
728 UG_ASSERT(i < nsh, "Wrong index.");
729 }
730
732 inline void check_multi_index(const MathVector<dim,int>& ind) const
733 {
734 UG_ASSERT(ind[0] <= (int)p && ind[0]>=0, "Wrong Multiindex.");
735 UG_ASSERT(ind[1] <= (int)p && ind[0]>=0, "Wrong Multiindex.");
736 UG_ASSERT(ind[0] + ind[1] <= (int)p && ind[0]>=0, "Wrong Multiindex.");
737 }
738
739 private:
741 size_t p;
742
744 size_t nsh;
745
746 std::vector<Polynomial1D> m_vPolynom;
747 std::vector<Polynomial1D> m_vDPolynom;
748
749 std::vector<MathVector<dim,int> > m_vMultiIndex;
750};
751
753// Quadrilateral
755
756template <int TOrder>
758 : public LagrangeLDS<ReferenceQuadrilateral>,
759 public BaseLSFS<LagrangeLSFS<ReferenceQuadrilateral, TOrder>, 2>
760{
761 private:
763 static const size_t p = TOrder;
764
767
768 public:
771
774
775 public:
777 static const size_t order = TOrder;
778
780 static const int dim = ReferenceQuadrilateral::dim;
781
783 static const size_t nsh = (p+1)*(p+1);
784
785 public:
787 LagrangeLSFS();
788
790 inline bool continuous() const {return true;}
791
793 inline size_t num_sh() const {return nsh;}
794
796 inline bool position(size_t i, MathVector<dim>& pos) const
797 {
798 // get Multi Index
799 MathVector<dim,int> ind = multi_index(i);
800
801 // set position
802 for(int d = 0; d < dim; ++d)
803 pos[d] = EquidistantLagrange1D::position(ind[d], p);
804
805 return true;
806 }
807
809 inline number shape(const size_t i, const MathVector<dim>& x) const
810 {
811 // forward
812 return shape(multi_index(i), x);
813 }
814
816 inline number shape(const MathVector<dim,int>& ind, const MathVector<dim>& x) const
817 {
818 check_multi_index(ind);
819 //ReferenceQuadrilateral::check_position(x);
820
821 return m_vPolynom[ ind[0] ].value(x[0])
822 * m_vPolynom[ ind[1] ].value(x[1]);
823 }
824
826 inline void grad(grad_type& g, const size_t i, const MathVector<dim>& x) const
827 {
828 grad(g, multi_index(i), x);
829 }
830
832 inline void grad(grad_type& g, const MathVector<dim,int> ind,
833 const MathVector<dim>& x) const
834 {
835 check_multi_index(ind);
836 //ReferenceQuadrilateral::check_position(x);
837
838 // loop dimensions
839 for(int d = 0; d < dim; ++d)
840 {
841 g[d] = m_vDPolynom[ind[d]].value(x[d]);
842
843 // multiply by all functions not depending on x[d]
844 for(int d2 = 0; d2 < dim; ++d2)
845 {
846 // skip own value
847 if(d2 == d) continue;
848
849 g[d] *= m_vPolynom[ind[d2]].value(x[d2]);
850 }
851 }
852 }
853
855 inline const MathVector<dim,int>& multi_index(size_t i) const
856 {
857 check_index(i);
858 return m_vMultiIndex[i];
859 }
860
862 inline size_t index(const MathVector<dim,int>& ind) const
863 {
864 check_multi_index(ind);
865 for(size_t i=0; i<nsh; ++i)
866 if(multi_index(i) == ind) return i;
867 UG_THROW("Index not found in LagrangeLSFS");
868 }
869
871 inline size_t mapped_index(const MathVector<dim,int>& ind) const
872 {
873 check_multi_index(ind);
874
875 return ind[1] * (p+1) + ind[0];
876 }
877
880 {
881 check_index(i);
882
883 return MathVector<dim,int>( i%(p+1), i/(p+1) );
884 }
885
887 inline void check_index(size_t i) const
888 {
889 UG_ASSERT(i < nsh, "Wrong index.");
890 }
891
893 inline void check_multi_index(const MathVector<dim,int>& ind) const
894 {
895 UG_ASSERT(ind[0] <= (int)p && ind[0] >= 0, "Wrong Multiindex.");
896 UG_ASSERT(ind[1] <= (int)p && ind[1] >= 0, "Wrong Multiindex.");
897 }
898
899 private:
900 Polynomial1D m_vPolynom[p+1];
901 Polynomial1D m_vDPolynom[p+1];
902
903 MathVector<dim,int> m_vMultiIndex[nsh];
904};
905
906
907template <>
909 : public LagrangeLDS<ReferenceQuadrilateral>,
910 public BaseLSFS<FlexLagrangeLSFS<ReferenceQuadrilateral>, 2>
911{
912 public:
914 static const int dim = ReferenceQuadrilateral::dim;
915
916 public:
918 FlexLagrangeLSFS() {set_order(1);}
919
921 FlexLagrangeLSFS(size_t order) {set_order(order);}
922
924 void set_order(size_t order);
925
927 inline bool continuous() const {return true;}
928
930 inline size_t num_sh() const {return nsh;}
931
933 inline bool position(size_t i, MathVector<dim>& pos) const
934 {
935 // get Multi Index
936 MathVector<dim,int> ind = multi_index(i);
937
938 // set position
939 for(int d = 0; d < dim; ++d)
940 pos[d] = EquidistantLagrange1D::position(ind[d], p);
941
942 return true;
943 }
944
946 inline number shape(const size_t i, const MathVector<dim>& x) const
947 {
948 // forward
949 return shape(multi_index(i), x);
950 }
951
953 inline number shape(const MathVector<dim,int>& ind, const MathVector<dim>& x) const
954 {
955 check_multi_index(ind);
956 //ReferenceQuadrilateral::check_position(x);
957
958 return m_vPolynom[ ind[0] ].value(x[0])
959 * m_vPolynom[ ind[1] ].value(x[1]);
960 }
961
963 inline void grad(grad_type& g, const size_t i, const MathVector<dim>& x) const
964 {
965 grad(g, multi_index(i), x);
966 }
967
969 inline void grad(grad_type& g, const MathVector<dim,int> ind,
970 const MathVector<dim>& x) const
971 {
972 check_multi_index(ind);
973 //ReferenceQuadrilateral::check_position(x);
974
975 // loop dimensions
976 for(int d = 0; d < dim; ++d)
977 {
978 g[d] = m_vDPolynom[ind[d]].value(x[d]);
979
980 // multiply by all functions not depending on x[d]
981 for(int d2 = 0; d2 < dim; ++d2)
982 {
983 // skip own value
984 if(d2 == d) continue;
985
986 g[d] *= m_vPolynom[ind[d2]].value(x[d2]);
987 }
988 }
989 }
990
992 inline const MathVector<dim,int>& multi_index(size_t i) const
993 {
994 check_index(i);
995 return m_vMultiIndex[i];
996 }
997
999 inline size_t index(const MathVector<dim,int>& ind) const
1000 {
1001 check_multi_index(ind);
1002 for(size_t i=0; i<nsh; ++i)
1003 if(multi_index(i) == ind) return i;
1004 UG_THROW("Index not found in LagrangeLSFS");
1005 }
1006
1008 inline size_t mapped_index(const MathVector<dim,int>& ind) const
1009 {
1010 check_multi_index(ind);
1011
1012 return ind[1] * (p+1) + ind[0];
1013 }
1014
1017 {
1018 check_index(i);
1019
1020 return MathVector<dim,int>( i%(p+1), i/(p+1) );
1021 }
1022
1024 inline void check_index(size_t i) const
1025 {
1026 UG_ASSERT(i < nsh, "Wrong index.");
1027 }
1028
1030 inline void check_multi_index(const MathVector<dim,int>& ind) const
1031 {
1032 UG_ASSERT(ind[0] <= (int)p && ind[0] >= 0, "Wrong Multiindex.");
1033 UG_ASSERT(ind[1] <= (int)p && ind[1] >= 0, "Wrong Multiindex.");
1034 }
1035
1036 private:
1038 size_t p;
1039
1041 size_t nsh;
1042
1043 std::vector<Polynomial1D> m_vPolynom;
1044 std::vector<Polynomial1D> m_vDPolynom;
1045
1046 std::vector<MathVector<dim,int> > m_vMultiIndex;
1047};
1048
1050// Tetrahedron
1052
1053template <int TOrder>
1055 : public LagrangeLDS<ReferenceTetrahedron>,
1056 public BaseLSFS<LagrangeLSFS<ReferenceTetrahedron, TOrder>, 3>
1057{
1058 private:
1060 static const size_t p = TOrder;
1061
1064
1065 public:
1068
1071
1072 public:
1074 static const size_t order = TOrder;
1075
1077 static const int dim = ReferenceTetrahedron::dim;
1078
1081
1082 public:
1084 LagrangeLSFS();
1085
1087 inline bool continuous() const {return true;}
1088
1090 inline size_t num_sh() const {return nsh;}
1091
1093 inline bool position(size_t i, MathVector<dim>& pos) const
1094 {
1095 // get Multi Index
1096 MathVector<dim,int> ind = multi_index(i);
1097
1098 // set position
1099 for(int d = 0; d < dim; ++d)
1101
1102 return true;
1103 }
1104
1106 inline number shape(const size_t i, const MathVector<dim>& x) const
1107 {
1108 // forward
1109 return shape(multi_index(i), x);
1110 }
1111
1113 inline number shape(const MathVector<dim,int>& ind, const MathVector<dim>& x) const
1114 {
1115 check_multi_index(ind);
1116 //ReferenceTetrahedron::check_position(x);
1117
1118 // get adjoint barycentric index
1119 const size_t i0 = p - ind[0] - ind[1] - ind[2];
1120 const number x0 = 1.0 - x[0] - x[1] - x[2];
1121
1122 return m_vPolynom[ ind[0] ].value(x[0])
1123 * m_vPolynom[ ind[1] ].value(x[1])
1124 * m_vPolynom[ ind[2] ].value(x[2])
1125 * m_vPolynom[ i0 ].value(x0);
1126 }
1127
1129 inline void grad(grad_type& g, const size_t i, const MathVector<dim>& x) const
1130 {
1131 grad(g, multi_index(i), x);
1132 }
1133
1135 inline void grad(grad_type& g, const MathVector<dim,int> ind,
1136 const MathVector<dim>& x) const
1137 {
1138 check_multi_index(ind);
1139 //ReferenceTetrahedron::check_position(x);
1140
1141 // get adjoint barycentric index and position
1142 const size_t i0 = p - ind[0] - ind[1] - ind[2];
1143 const number x0 = 1 - x[0] - x[1] - x[2];
1144
1145 UG_ASSERT(i0 <= p, "Wrong Multiindex.");
1146 UG_ASSERT(x0 <= 1.0+SMALL && x0 >= -SMALL, "Wrong Position.");
1147
1148 // loop dimensions
1149 for(int d = 0; d < dim; ++d)
1150 {
1151 g[d] = m_vDPolynom[ind[d]].value(x[d])
1152 * m_vPolynom[i0].value(x0);
1153 g[d] += (-1) * m_vDPolynom[i0].value(x0)
1154 * m_vPolynom[ind[d]].value(x[d]);
1155
1156 // multiply by all functions not depending on x[d]
1157 for(int d2 = 0; d2 < dim; ++d2)
1158 {
1159 // skip own value
1160 if(d2 == d) continue;
1161
1162 g[d] *= m_vPolynom[ind[d2]].value(x[d2]);
1163 }
1164 }
1165 }
1166
1168 inline const MathVector<dim,int>& multi_index(size_t i) const
1169 {
1170 check_index(i);
1171 return m_vMultiIndex[i];
1172 }
1173
1175 inline size_t index(const MathVector<dim,int>& ind) const
1176 {
1177 check_multi_index(ind);
1178 for(size_t i=0; i<nsh; ++i)
1179 if(multi_index(i) == ind) return i;
1180 UG_THROW("Index not found in LagrangeLSFS");
1181 }
1182
1184 inline size_t mapped_index(const MathVector<dim,int>& ind) const
1185 {
1186 check_multi_index(ind);
1187
1188 // add x range
1189 size_t res = ind[0];
1190
1191 // add y range
1192 for(int i = 0; i < ind[1]; ++i)
1193 res += (p+1-ind[2]-i);
1194
1195 // add z range
1196 for(int i2 = 0; i2 < ind[2]; ++i2)
1197 res += BinomCoeff(p+2-i2, p-i2);
1198
1199 check_index(res);
1200 return res;
1201 }
1202
1205 {
1206 check_index(i);
1207
1208 int i0 = i, i1 = 0, i2 = 0;
1209 for(i2 = 0; i2 <= (int)p; ++i2)
1210 {
1211 const int binom = BinomCoeff(p+2-i2, p-i2);
1212
1213 // if i2 is correct
1214 const int diff = i0 - binom;
1215 if(diff < 0)
1216 {
1217 for(i1 = 0; i1 <= (int)p; ++i1)
1218 {
1219 // if i1 is correct return values
1220 const int diff = i0 - (p+1-i2-i1);
1221 if(diff < 0)
1222 return MathVector<dim,int>( i0, i1, i2);
1223
1224 // else decrease i1
1225 i0 = diff;
1226 }
1227 }
1228 // else go one level lower
1229 else
1230 i0 = diff;
1231 }
1232
1233 UG_ASSERT(i0 >= 0, "i0 is negative ("<<i0<<")");
1234 UG_ASSERT(i1 >= 0, "i1 is negative ("<<i1<<")");
1235 UG_ASSERT(i2 >= 0, "i1 is negative ("<<i2<<")");
1236
1237 UG_ASSERT(0, "Should not reach this line.");
1238 return MathVector<dim,int>( i0, i1, i2);
1239 }
1240
1242 inline void check_index(size_t i) const
1243 {
1244 UG_ASSERT(i < nsh, "Wrong index.");
1245 }
1246
1248 inline void check_multi_index(const MathVector<dim,int>& ind) const
1249 {
1250 UG_ASSERT(ind[0] <= (int)p && ind[0] >= 0, "Wrong Multiindex.");
1251 UG_ASSERT(ind[1] <= (int)p && ind[1] >= 0, "Wrong Multiindex.");
1252 UG_ASSERT(ind[2] <= (int)p && ind[2] >= 0, "Wrong Multiindex.");
1253 UG_ASSERT(ind[0] + ind[1] + ind[2] <= (int)p, "Wrong Multiindex.");
1254 }
1255
1256 private:
1257 Polynomial1D m_vPolynom[p+1];
1258 Polynomial1D m_vDPolynom[p+1];
1259
1260 MathVector<dim,int> m_vMultiIndex[nsh];
1261};
1262
1263
1264template <>
1266 : public LagrangeLDS<ReferenceTetrahedron>,
1267 public BaseLSFS<FlexLagrangeLSFS<ReferenceTetrahedron>, 3>
1268{
1269 public:
1271 static const int dim = ReferenceTetrahedron::dim;
1272
1273 public:
1275 FlexLagrangeLSFS() {set_order(1);}
1276
1278 FlexLagrangeLSFS(size_t order) {set_order(order);}
1279
1281 void set_order(size_t order);
1282
1284 inline bool continuous() const {return true;}
1285
1287 inline size_t num_sh() const {return nsh;}
1288
1290 inline bool position(size_t i, MathVector<dim>& pos) const
1291 {
1292 // get Multi Index
1293 MathVector<dim,int> ind = multi_index(i);
1294
1295 // set position
1296 for(int d = 0; d < dim; ++d)
1298
1299 return true;
1300 }
1301
1303 inline number shape(const size_t i, const MathVector<dim>& x) const
1304 {
1305 // forward
1306 return shape(multi_index(i), x);
1307 }
1308
1310 inline number shape(const MathVector<dim,int>& ind, const MathVector<dim>& x) const
1311 {
1312 check_multi_index(ind);
1313 //ReferenceTetrahedron::check_position(x);
1314
1315 // get adjoint barycentric index
1316 const size_t i0 = p - ind[0] - ind[1] - ind[2];
1317 const number x0 = 1.0 - x[0] - x[1] - x[2];
1318
1319 return m_vPolynom[ ind[0] ].value(x[0])
1320 * m_vPolynom[ ind[1] ].value(x[1])
1321 * m_vPolynom[ ind[2] ].value(x[2])
1322 * m_vPolynom[ i0 ].value(x0);
1323 }
1324
1326 inline void grad(grad_type& g, const size_t i, const MathVector<dim>& x) const
1327 {
1328 grad(g, multi_index(i), x);
1329 }
1330
1332 inline void grad(grad_type& g, const MathVector<dim,int> ind,
1333 const MathVector<dim>& x) const
1334 {
1335 check_multi_index(ind);
1336 //ReferenceTetrahedron::check_position(x);
1337
1338 // get adjoint barycentric index and position
1339 const size_t i0 = p - ind[0] - ind[1] - ind[2];
1340 const number x0 = 1 - x[0] - x[1] - x[2];
1341
1342 UG_ASSERT(i0 <= p, "Wrong Multiindex.");
1343 UG_ASSERT(x0 <= 1.0+SMALL && x0 >= -SMALL, "Wrong Position.");
1344
1345 // loop dimensions
1346 for(int d = 0; d < dim; ++d)
1347 {
1348 g[d] = m_vDPolynom[ind[d]].value(x[d])
1349 * m_vPolynom[i0].value(x0);
1350 g[d] += (-1) * m_vDPolynom[i0].value(x0)
1351 * m_vPolynom[ind[d]].value(x[d]);
1352
1353 // multiply by all functions not depending on x[d]
1354 for(int d2 = 0; d2 < dim; ++d2)
1355 {
1356 // skip own value
1357 if(d2 == d) continue;
1358
1359 g[d] *= m_vPolynom[ind[d2]].value(x[d2]);
1360 }
1361 }
1362 }
1363
1365 inline const MathVector<dim,int>& multi_index(size_t i) const
1366 {
1367 check_index(i);
1368 return m_vMultiIndex[i];
1369 }
1370
1372 inline size_t index(const MathVector<dim,int>& ind) const
1373 {
1374 check_multi_index(ind);
1375 for(size_t i=0; i<nsh; ++i)
1376 if(multi_index(i) == ind) return i;
1377 UG_THROW("Index not found in LagrangeLSFS");
1378 }
1379
1381 inline size_t mapped_index(const MathVector<dim,int>& ind) const
1382 {
1383 check_multi_index(ind);
1384
1385 // add x range
1386 size_t res = ind[0];
1387
1388 // add y range
1389 for(int i = 0; i < ind[1]; ++i)
1390 res += (p+1-ind[2]-i);
1391
1392 // add z range
1393 for(int i2 = 0; i2 < ind[2]; ++i2)
1394 res += BinomCoeff(p+2-i2, p-i2);
1395
1396 check_index(res);
1397 return res;
1398 }
1399
1402 {
1403 check_index(i);
1404
1405 int i0 = i, i1 = 0, i2 = 0;
1406 for(i2 = 0; i2 <= (int)p; ++i2)
1407 {
1408 const int binom = BinomCoeff(p+2-i2, p-i2);
1409
1410 // if i2 is correct
1411 const int diff = i0 - binom;
1412 if(diff < 0)
1413 {
1414 for(i1 = 0; i1 <= (int)p; ++i1)
1415 {
1416 // if i1 is correct return values
1417 const int diff = i0 - (p+1-i2-i1);
1418 if(diff < 0)
1419 return MathVector<dim,int>( i0, i1, i2);
1420
1421 // else decrease i1
1422 i0 = diff;
1423 }
1424 }
1425 // else go one level lower
1426 else
1427 i0 = diff;
1428 }
1429
1430 UG_ASSERT(i0 >= 0, "i0 is negative ("<<i0<<")");
1431 UG_ASSERT(i1 >= 0, "i1 is negative ("<<i1<<")");
1432 UG_ASSERT(i2 >= 0, "i1 is negative ("<<i2<<")");
1433
1434 UG_ASSERT(0, "Should not reach this line.");
1435 return MathVector<dim,int>( i0, i1, i2);
1436 }
1437
1439 inline void check_index(size_t i) const
1440 {
1441 UG_ASSERT(i < nsh, "Wrong index.");
1442 }
1443
1445 inline void check_multi_index(const MathVector<dim,int>& ind) const
1446 {
1447 UG_ASSERT(ind[0] <= (int)p && ind[0] >= 0, "Wrong Multiindex.");
1448 UG_ASSERT(ind[1] <= (int)p && ind[1] >= 0, "Wrong Multiindex.");
1449 UG_ASSERT(ind[2] <= (int)p && ind[2] >= 0, "Wrong Multiindex.");
1450 UG_ASSERT(ind[0] + ind[1] + ind[2] <= (int)p, "Wrong Multiindex.");
1451 }
1452
1453 private:
1455 size_t p;
1456
1458 size_t nsh;
1459
1460 std::vector<Polynomial1D> m_vPolynom;
1461 std::vector<Polynomial1D> m_vDPolynom;
1462
1463 std::vector<MathVector<dim,int> > m_vMultiIndex;
1464};
1465
1467// Prism
1469
1470template <int TOrder>
1472 : public LagrangeLDS<ReferencePrism>,
1473 public BaseLSFS<LagrangeLSFS<ReferencePrism, TOrder>, 3>
1474{
1475 private:
1477 static const size_t p = TOrder;
1478
1480 static const size_t dofPerLayer = BinomialCoefficient<2 + p, p>::value;
1481
1484
1485 public:
1488
1491
1492 public:
1494 static const size_t order = TOrder;
1495
1497 static const int dim = ReferencePrism::dim;
1498
1500 static const size_t nsh = dofPerLayer*(p+1);
1501
1502 public:
1504 LagrangeLSFS();
1505
1507 inline bool continuous() const {return true;}
1508
1510 inline size_t num_sh() const {return nsh;}
1511
1513 inline bool position(size_t i, MathVector<dim>& pos) const
1514 {
1515 // get Multi Index
1516 MathVector<dim,int> ind = multi_index(i);
1517
1518 // set position
1519 for(int d = 0; d < 2; ++d)
1521
1522 pos[2] = EquidistantLagrange1D::position(ind[2], p);
1523
1524 return true;
1525 }
1526
1528 inline number shape(const size_t i, const MathVector<dim>& x) const
1529 {
1530 // forward
1531 return shape(multi_index(i), x);
1532 }
1533
1535 inline number shape(const MathVector<dim,int>& ind, const MathVector<dim>& x) const
1536 {
1537 check_multi_index(ind);
1538 //ReferencePrism::check_position(x);
1539
1540 // get adjoint barycentric index
1541 const size_t i0 = p - ind[0] - ind[1];
1542 const number x0 = 1.0 - x[0] - x[1];
1543
1544 // x-y direction
1545 return m_vTruncPolynom[ ind[0] ].value(x[0])
1546 * m_vTruncPolynom[ ind[1] ].value(x[1])
1547 * m_vTruncPolynom[ i0 ].value( x0 )
1548 // z direction
1549 * m_vPolynom[ ind[2] ].value(x[2]);
1550 }
1551
1553 void grad(grad_type& g, const size_t i, const MathVector<dim>& x) const
1554 {
1555 grad(g, multi_index(i), x);
1556 }
1557
1560 const MathVector<dim>& x) const
1561 {
1562 check_multi_index(ind);
1563 //ReferencePrism::check_position(x);
1564
1565 // get adjoint barycentric index and position
1566 const size_t i0 = p - ind[0] - ind[1];
1567 const number x0 = 1 - x[0] - x[1];
1568
1569 UG_ASSERT(i0 <= p, "Wrong Multiindex.");
1570 UG_ASSERT(x0 <= 1.0+SMALL && x0 >= -SMALL, "Wrong Position.");
1571
1572 // x-y gradient
1573 for(size_t d = 0; d < 2; ++d)
1574 {
1575 g[d] = m_vDTruncPolynom[ind[d]].value(x[d])
1576 * m_vTruncPolynom[i0].value(x0);
1577 g[d] += (-1) * m_vDTruncPolynom[i0].value(x0)
1578 * m_vTruncPolynom[ind[d]].value(x[d]);
1579
1580 // multiply by all functions not depending on x[d]
1581 for(size_t d2 = 0; d2 < 2; ++d2)
1582 {
1583 // skip own value
1584 if(d2 == d) continue;
1585
1586 g[d] *= m_vTruncPolynom[ind[d2]].value(x[d2]);
1587 }
1588
1589 // multiply by z coordinate
1590 g[d] *= m_vPolynom[ind[2]].value(x[2]);
1591 }
1592
1593 // z gradient
1594 g[2] = m_vDPolynom[ind[2]].value(x[2]);
1595 g[2] *= m_vTruncPolynom[ ind[0] ].value(x[0])
1596 * m_vTruncPolynom[ ind[1] ].value(x[1])
1597 * m_vTruncPolynom[ i0 ].value( x0 );
1598 }
1599
1601 inline const MathVector<dim,int>& multi_index(size_t i) const
1602 {
1603 check_index(i);
1604 return m_vMultiIndex[i];
1605 }
1606
1608 inline size_t index(const MathVector<dim,int>& ind) const
1609 {
1610 check_multi_index(ind);
1611 for(size_t i=0; i<nsh; ++i)
1612 if(multi_index(i) == ind) return i;
1613 UG_THROW("Index not found in LagrangeLSFS");
1614 }
1615
1617 inline size_t mapped_index(const MathVector<dim,int>& ind) const
1618 {
1619 check_multi_index(ind);
1620
1621 size_t res = ind[0];
1622 for(int i = 0; i < ind[1]; ++i)
1623 res += (p+1-i);
1624
1625 // add height
1626 res += ind[2] * dofPerLayer;
1627
1628 return res;
1629 }
1630
1633 {
1634 check_index(i);
1635
1636 const size_t i2 = i / dofPerLayer;
1637
1638 int i0 = i - i2*dofPerLayer, i1;
1639 for(i1 = 0; i1 < (int)p; ++i1)
1640 {
1641 const int diff = i0 - (p+1-i1);
1642 if(diff < 0)
1643 break;
1644 i0 = diff;
1645 }
1646
1647 return MathVector<dim,int>( i0, i1, i2);
1648 }
1649
1651 inline void check_index(size_t i) const
1652 {
1653 UG_ASSERT(i < nsh, "Wrong index.");
1654 }
1655
1657 inline void check_multi_index(const MathVector<dim,int>& ind) const
1658 {
1659 UG_ASSERT(ind[0] <= (int)p && ind[0] >= 0, "Wrong Multiindex.");
1660 UG_ASSERT(ind[1] <= (int)p && ind[1] >= 0, "Wrong Multiindex.");
1661 UG_ASSERT(ind[0] + ind[1] <= (int)p, "Wrong Multiindex.");
1662 UG_ASSERT(ind[2] <= (int)p && ind[2] >= 0, "Wrong Multiindex.");
1663 }
1664
1665 private:
1666 Polynomial1D m_vPolynom[p+1];
1667 Polynomial1D m_vDPolynom[p+1];
1668 Polynomial1D m_vTruncPolynom[p+1];
1669 Polynomial1D m_vDTruncPolynom[p+1];
1670
1671 MathVector<dim,int> m_vMultiIndex[nsh];
1672};
1673
1674
1675template <>
1677 : public LagrangeLDS<ReferencePrism>,
1678 public BaseLSFS<FlexLagrangeLSFS<ReferencePrism>, 3>
1679{
1680 public:
1682 static const int dim = ReferencePrism::dim;
1683
1684 public:
1686 FlexLagrangeLSFS() {set_order(1);}
1687
1689 FlexLagrangeLSFS(size_t order) {set_order(order);}
1690
1692 void set_order(size_t order);
1693
1695 inline bool continuous() const {return true;}
1696
1698 inline size_t num_sh() const {return nsh;}
1699
1701 inline bool position(size_t i, MathVector<dim>& pos) const
1702 {
1703 // get Multi Index
1704 MathVector<dim,int> ind = multi_index(i);
1705
1706 // set position
1707 for(int d = 0; d < 2; ++d)
1709
1710 pos[2] = EquidistantLagrange1D::position(ind[2], p);
1711
1712 return true;
1713 }
1714
1716 inline number shape(const size_t i, const MathVector<dim>& x) const
1717 {
1718 // forward
1719 return shape(multi_index(i), x);
1720 }
1721
1723 inline number shape(const MathVector<dim,int>& ind, const MathVector<dim>& x) const
1724 {
1725 check_multi_index(ind);
1726 //ReferencePrism::check_position(x);
1727
1728 // get adjoint barycentric index
1729 const size_t i0 = p - ind[0] - ind[1];
1730 const number x0 = 1.0 - x[0] - x[1];
1731
1732 // x-y direction
1733 return m_vTruncPolynom[ ind[0] ].value(x[0])
1734 * m_vTruncPolynom[ ind[1] ].value(x[1])
1735 * m_vTruncPolynom[ i0 ].value( x0 )
1736 // z direction
1737 * m_vPolynom[ ind[2] ].value(x[2]);
1738 }
1739
1741 void grad(grad_type& g, const size_t i, const MathVector<dim>& x) const
1742 {
1743 grad(g, multi_index(i), x);
1744 }
1745
1748 const MathVector<dim>& x) const
1749 {
1750 check_multi_index(ind);
1751 //ReferencePrism::check_position(x);
1752
1753 // get adjoint barycentric index and position
1754 const size_t i0 = p - ind[0] - ind[1];
1755 const number x0 = 1 - x[0] - x[1];
1756
1757 UG_ASSERT(i0 <= p, "Wrong Multiindex.");
1758 UG_ASSERT(x0 <= 1.0+SMALL && x0 >= -SMALL, "Wrong Position.");
1759
1760 // x-y gradient
1761 for(size_t d = 0; d < 2; ++d)
1762 {
1763 g[d] = m_vDTruncPolynom[ind[d]].value(x[d])
1764 * m_vTruncPolynom[i0].value(x0);
1765 g[d] += (-1) * m_vDTruncPolynom[i0].value(x0)
1766 * m_vTruncPolynom[ind[d]].value(x[d]);
1767
1768 // multiply by all functions not depending on x[d]
1769 for(size_t d2 = 0; d2 < 2; ++d2)
1770 {
1771 // skip own value
1772 if(d2 == d) continue;
1773
1774 g[d] *= m_vTruncPolynom[ind[d2]].value(x[d2]);
1775 }
1776
1777 // multiply by z coordinate
1778 g[d] *= m_vPolynom[ind[2]].value(x[2]);
1779 }
1780
1781 // z gradient
1782 g[2] = m_vDPolynom[ind[2]].value(x[2]);
1783 g[2] *= m_vTruncPolynom[ ind[0] ].value(x[0])
1784 * m_vTruncPolynom[ ind[1] ].value(x[1])
1785 * m_vTruncPolynom[ i0 ].value( x0 );
1786 }
1787
1789 inline const MathVector<dim,int>& multi_index(size_t i) const
1790 {
1791 check_index(i);
1792 return m_vMultiIndex[i];
1793 }
1794
1796 inline size_t index(const MathVector<dim,int>& ind) const
1797 {
1798 check_multi_index(ind);
1799 for(size_t i=0; i<nsh; ++i)
1800 if(multi_index(i) == ind) return i;
1801 UG_THROW("Index not found in LagrangeLSFS");
1802 }
1803
1805 inline size_t mapped_index(const MathVector<dim,int>& ind) const
1806 {
1807 check_multi_index(ind);
1808
1809 size_t res = ind[0];
1810 for(int i = 0; i < ind[1]; ++i)
1811 res += (p+1-i);
1812
1813 // add height
1814 res += ind[2] * dofPerLayer;
1815
1816 return res;
1817 }
1818
1821 {
1822 check_index(i);
1823
1824 const size_t i2 = i / dofPerLayer;
1825
1826 int i0 = i - i2*dofPerLayer, i1;
1827 for(i1 = 0; i1 < (int)p; ++i1)
1828 {
1829 const int diff = i0 - (p+1-i1);
1830 if(diff < 0)
1831 break;
1832 i0 = diff;
1833 }
1834
1835 return MathVector<dim,int>( i0, i1, i2);
1836 }
1837
1839 inline void check_index(size_t i) const
1840 {
1841 UG_ASSERT(i < nsh, "Wrong index.");
1842 }
1843
1845 inline void check_multi_index(const MathVector<dim,int>& ind) const
1846 {
1847 UG_ASSERT(ind[0] <= (int)p && ind[0] >= 0, "Wrong Multiindex.");
1848 UG_ASSERT(ind[1] <= (int)p && ind[1] >= 0, "Wrong Multiindex.");
1849 UG_ASSERT(ind[0] + ind[1] <= (int)p, "Wrong Multiindex.");
1850 UG_ASSERT(ind[2] <= (int)p && ind[2] >= 0, "Wrong Multiindex.");
1851 }
1852
1853 private:
1855 size_t p;
1856
1858 size_t nsh;
1859
1862
1863 std::vector<Polynomial1D> m_vPolynom;
1864 std::vector<Polynomial1D> m_vDPolynom;
1865 std::vector<Polynomial1D> m_vTruncPolynom;
1866 std::vector<Polynomial1D> m_vDTruncPolynom;
1867
1868 std::vector<MathVector<dim,int> > m_vMultiIndex;
1869};
1870
1872// Pyramid
1874
1875namespace {
1876template <int p>
1877struct NumberOfDoFsOfPyramid{
1878 enum{value = NumberOfDoFsOfPyramid<p-1>::value + (p+1)*(p+1)};
1879};
1880
1881// specialization to end recursion
1882template <> struct NumberOfDoFsOfPyramid<1>{enum {value = 5};};
1883template <> struct NumberOfDoFsOfPyramid<0>{enum {value = 0};};
1884template <> struct NumberOfDoFsOfPyramid<-1>{enum {value = 0};};
1885} // end empty namespace
1886
1887// todo: Implement higher order (impossible ?)
1888// NOTE: Currently only 1st order is implemented. There is no shape function
1889// set for pyramids, that is continuous and allows a continuous
1890// derivative in the inner of the pyramid. This is basically, since
1891// one regards the pyramid as two tetrahedrons, glued together.
1892template <int TOrder>
1894 : public LagrangeLDS<ReferencePyramid>,
1895 public BaseLSFS<LagrangeLSFS<ReferencePyramid, TOrder>, 3>
1896{
1897 private:
1899 static const size_t p = TOrder;
1900
1903
1904 public:
1907
1910
1911 public:
1913 static const size_t order = TOrder;
1914
1916 static const int dim = 3; //reference_element_type::dim; (compile error on OSX 10.5)
1917
1919 static const size_t nsh = NumberOfDoFsOfPyramid<p>::value;
1920
1921 public:
1923 LagrangeLSFS();
1924
1926 inline bool continuous() const {return true;}
1927
1929 inline size_t num_sh() const {return nsh;}
1930
1932 inline bool position(size_t i, MathVector<dim>& pos) const
1933 {
1934 // get Multi Index
1935 MathVector<dim,int> ind = multi_index(i);
1936
1937 // set position
1938 for(int d = 0; d < dim; ++d)
1939 pos[d] = EquidistantLagrange1D::position(ind[d], p);
1940
1941 return true;
1942 }
1943
1945 inline number shape(const size_t i, const MathVector<dim>& x) const
1946 {
1947 // only first order
1948 if(p != 1) UG_THROW("Only 1. order Lagrange Pyramid implemented.");
1949
1950 // smaller value of x and y
1951 number m = x[0];
1952 if (x[0] > x[1]) m = x[1];
1953
1954 switch(i)
1955 {
1956 case 0 : return((1.0-x[0])*(1.0-x[1]) + x[2]*(m-1.0));
1957 case 1 : return(x[0]*(1.0-x[1]) - x[2]*m);
1958 case 2 : return(x[0]*x[1] + x[2]*m);
1959 case 3 : return((1.0-x[0])*x[1] - x[2]*m);
1960 case 4 : return(x[2]);
1961 default: UG_THROW("Wrong index "<< i<<" in Pyramid");
1962 }
1963 }
1964
1966 inline number shape(const MathVector<dim,int>& ind, const MathVector<dim>& x) const
1967 {
1968 check_multi_index(ind);
1969 //ReferencePyramid::check_position(x);
1970
1971 // forward
1972 return shape(index(ind), x);
1973 }
1974
1976 inline void grad(grad_type& g, const size_t i, const MathVector<dim>& x) const
1977 {
1978 // only first order
1979 if(p != 1) UG_THROW("Only 1. order Lagrange Pyramid implemented.");
1980
1981 int m = 0;
1982 if (x[0] > x[1]) m = 1;
1983
1984 switch(i)
1985 {
1986 case 0:
1987 g[0] = -(1.0-x[1]);
1988 g[1] = -(1.0-x[0]) + x[2];
1989 g[2] = -(1.0-x[1]);
1990 g[m] += x[2];
1991 break;
1992 case 1:
1993 g[0] = (1.0-x[1]);
1994 g[1] = -x[0];
1995 g[2] = -x[1];
1996 g[m] -= x[2];
1997 break;
1998 case 2:
1999 g[0] = x[1];
2000 g[1] = x[0];
2001 g[2] = x[1];
2002 g[m] += x[2];
2003 break;
2004 case 3:
2005 g[0] = -x[1];
2006 g[1] = 1.0-x[0];
2007 g[2] = -x[1];
2008 g[m] -= x[2];
2009 break;
2010 case 4:
2011 g[0] = 0.0;
2012 g[1] = 0.0;
2013 g[2] = 1.0;
2014 break;
2015 default: UG_THROW("Wrong index "<< i<<" in Pyramid");
2016 }
2017
2018 }
2019
2021 inline void grad(grad_type& g, const MathVector<dim,int> ind,
2022 const MathVector<dim>& x) const
2023 {
2024 grad(g, index(ind), x);
2025 }
2026
2028 inline const MathVector<dim,int>& multi_index(size_t i) const
2029 {
2030 check_index(i);
2031 return m_vMultiIndex[i];
2032 }
2033
2035 inline size_t index(const MathVector<dim,int>& ind) const
2036 {
2037 check_multi_index(ind);
2038 for(size_t i=0; i<nsh; ++i)
2039 if(multi_index(i) == ind) return i;
2040 UG_THROW("Index not found in LagrangeLSFS");
2041 }
2042
2044 inline size_t mapped_index(const MathVector<dim,int>& ind) const
2045 {
2046 check_multi_index(ind);
2047
2048 size_t res = 0;
2049
2050 // add layers that are completely filled
2051 for(int i2 = 0; i2 < ind[2]; ++i2)
2052 res += (p+1-i2)*(p+1-i2);
2053
2054 // add dofs of top z-layer
2055 res += ind[1] * (p+1-ind[2]) + ind[0];
2056
2057 check_index(res);
2058 return res;
2059 }
2060
2063 {
2064 check_index(i);
2065
2066 // get z layer
2067 int iTmp = i;
2068 int i2;
2069 for(i2 = 0; i2 < (int)p; ++i2)
2070 {
2071 const int diff = iTmp - (p+1-i2)*(p+1-i2);
2072 if(diff < 0) break;
2073
2074 iTmp = diff;
2075 }
2076
2077 return MathVector<dim,int>( iTmp%(p+1-i2), iTmp/(p+1-i2), i2);
2078 }
2079
2081 inline void check_index(size_t i) const
2082 {
2083 UG_ASSERT(i < nsh, "Wrong index.");
2084 }
2085
2087 inline void check_multi_index(const MathVector<dim,int>& ind) const
2088 {
2089 UG_ASSERT(ind[0] <= (int)p-ind[2] && ind[0] >= 0, "Wrong Multiindex.");
2090 UG_ASSERT(ind[1] <= (int)p-ind[2] && ind[1] >= 0, "Wrong Multiindex.");
2091 UG_ASSERT(ind[2] <= (int)p && ind[2] >= 0, "Wrong Multiindex.");
2092 }
2093
2094 private:
2095 std::vector<std::vector<Polynomial1D> > m_vvPolynom;
2096 std::vector<std::vector<Polynomial1D> > m_vvDPolynom;
2097
2098 MathVector<dim,int> m_vMultiIndex[nsh];
2099};
2100
2102// Hexahedron
2104
2105template <int TOrder>
2107 : public LagrangeLDS<ReferenceHexahedron>,
2108 public BaseLSFS<LagrangeLSFS<ReferenceHexahedron, TOrder>, 3>
2109{
2110 private:
2112 static const size_t p = TOrder;
2113
2116
2117 public:
2120
2123
2124 public:
2126 static const size_t order = TOrder;
2127
2129 static const int dim = ReferenceHexahedron::dim;
2130
2132 static const size_t nsh = (p+1)*(p+1)*(p+1);
2133
2134 public:
2136 LagrangeLSFS();
2137
2139 inline bool continuous() const {return true;}
2140
2142 inline size_t num_sh() const {return nsh;}
2143
2145 inline bool position(size_t i, MathVector<dim>& pos) const
2146 {
2147 // get Multi Index
2148 MathVector<dim,int> ind = multi_index(i);
2149
2150 // set position
2151 for(int d = 0; d < dim; ++d)
2152 pos[d] = EquidistantLagrange1D::position(ind[d], p);
2153
2154 return true;
2155 }
2156
2158 inline number shape(const size_t i, const MathVector<dim>& x) const
2159 {
2160 // forward
2161 return shape(multi_index(i), x);
2162 }
2163
2165 inline number shape(const MathVector<dim,int>& ind, const MathVector<dim>& x) const
2166 {
2167 check_multi_index(ind);
2168 //ReferenceHexahedron::check_position(x);
2169
2170 return m_vPolynom[ ind[0] ].value(x[0])
2171 * m_vPolynom[ ind[1] ].value(x[1])
2172 * m_vPolynom[ ind[2] ].value(x[2]);
2173 }
2174
2176 inline void grad(grad_type& g, const size_t i, const MathVector<dim>& x) const
2177 {
2178 grad(g, multi_index(i), x);
2179 }
2180
2182 inline void grad(grad_type& g, const MathVector<dim,int> ind,
2183 const MathVector<dim>& x) const
2184 {
2185 check_multi_index(ind);
2186 //ReferenceHexahedron::check_position(x);
2187
2188 // loop dimensions
2189 for(int d = 0; d < dim; ++d)
2190 {
2191 g[d] = m_vDPolynom[ind[d]].value(x[d]);
2192
2193 // multiply by all functions not depending on x[d]
2194 for(int d2 = 0; d2 < dim; ++d2)
2195 {
2196 // skip own value
2197 if(d2 == d) continue;
2198
2199 g[d] *= m_vPolynom[ind[d2]].value(x[d2]);
2200 }
2201 }
2202 }
2203
2205 inline const MathVector<dim,int>& multi_index(size_t i) const
2206 {
2207 check_index(i);
2208 return m_vMultiIndex[i];
2209 }
2210
2212 inline size_t index(const MathVector<dim,int>& ind) const
2213 {
2214 check_multi_index(ind);
2215 for(size_t i=0; i<nsh; ++i)
2216 if(multi_index(i) == ind) return i;
2217 UG_THROW("Index not found in LagrangeLSFS");
2218 }
2219
2221 inline size_t mapped_index(const MathVector<dim,int>& ind) const
2222 {
2223 check_multi_index(ind);
2224
2225 return ind[2] * (p+1)*(p+1) + ind[1] * (p+1) + ind[0];
2226 }
2227
2230 {
2231 check_index(i);
2232
2233 return MathVector<dim,int>( i%(p+1), i/(p+1)%(p+1), i/((p+1)*(p+1)));
2234 }
2235
2237 inline void check_index(size_t i) const
2238 {
2239 UG_ASSERT(i < nsh, "Wrong index.");
2240 }
2241
2243 inline void check_multi_index(const MathVector<dim,int>& ind) const
2244 {
2245 UG_ASSERT(ind[0] <= (int)p && ind[0] >= 0, "Wrong Multiindex.");
2246 UG_ASSERT(ind[1] <= (int)p && ind[1] >= 0, "Wrong Multiindex.");
2247 UG_ASSERT(ind[2] <= (int)p && ind[2] >= 0, "Wrong Multiindex.");
2248 }
2249
2250 private:
2251 Polynomial1D m_vPolynom[p+1];
2252 Polynomial1D m_vDPolynom[p+1];
2253
2254 MathVector<dim,int> m_vMultiIndex[nsh];
2255};
2256
2257template <>
2259 : public LagrangeLDS<ReferenceHexahedron>,
2260 public BaseLSFS<FlexLagrangeLSFS<ReferenceHexahedron>, 3>
2261{
2262 public:
2264 static const int dim = ReferenceHexahedron::dim;
2265
2266 public:
2268 FlexLagrangeLSFS() {set_order(1);}
2269
2271 FlexLagrangeLSFS(size_t order) {set_order(order);}
2272
2274 void set_order(size_t order);
2275
2277 inline bool continuous() const {return true;}
2278
2280 inline size_t num_sh() const {return nsh;}
2281
2283 inline bool position(size_t i, MathVector<dim>& pos) const
2284 {
2285 // get Multi Index
2286 MathVector<dim,int> ind = multi_index(i);
2287
2288 // set position
2289 for(int d = 0; d < dim; ++d)
2290 pos[d] = EquidistantLagrange1D::position(ind[d], p);
2291
2292 return true;
2293 }
2294
2296 inline number shape(const size_t i, const MathVector<dim>& x) const
2297 {
2298 // forward
2299 return shape(multi_index(i), x);
2300 }
2301
2303 inline number shape(const MathVector<dim,int>& ind, const MathVector<dim>& x) const
2304 {
2305 check_multi_index(ind);
2306 //ReferenceHexahedron::check_position(x);
2307
2308 return m_vPolynom[ ind[0] ].value(x[0])
2309 * m_vPolynom[ ind[1] ].value(x[1])
2310 * m_vPolynom[ ind[2] ].value(x[2]);
2311 }
2312
2314 inline void grad(grad_type& g, const size_t i, const MathVector<dim>& x) const
2315 {
2316 grad(g, multi_index(i), x);
2317 }
2318
2320 inline void grad(grad_type& g, const MathVector<dim,int> ind,
2321 const MathVector<dim>& x) const
2322 {
2323 check_multi_index(ind);
2324 //ReferenceHexahedron::check_position(x);
2325
2326 // loop dimensions
2327 for(int d = 0; d < dim; ++d)
2328 {
2329 g[d] = m_vDPolynom[ind[d]].value(x[d]);
2330
2331 // multiply by all functions not depending on x[d]
2332 for(int d2 = 0; d2 < dim; ++d2)
2333 {
2334 // skip own value
2335 if(d2 == d) continue;
2336
2337 g[d] *= m_vPolynom[ind[d2]].value(x[d2]);
2338 }
2339 }
2340 }
2341
2343 inline const MathVector<dim,int>& multi_index(size_t i) const
2344 {
2345 check_index(i);
2346 return m_vMultiIndex[i];
2347 }
2348
2350 inline size_t index(const MathVector<dim,int>& ind) const
2351 {
2352 check_multi_index(ind);
2353 for(size_t i=0; i<nsh; ++i)
2354 if(multi_index(i) == ind) return i;
2355 UG_THROW("Index not found in LagrangeLSFS");
2356 }
2357
2359 inline size_t mapped_index(const MathVector<dim,int>& ind) const
2360 {
2361 check_multi_index(ind);
2362
2363 return ind[2] * (p+1)*(p+1) + ind[1] * (p+1) + ind[0];
2364 }
2365
2368 {
2369 check_index(i);
2370
2371 return MathVector<dim,int>( i%(p+1), i/(p+1)%(p+1), i/((p+1)*(p+1)));
2372 }
2373
2375 inline void check_index(size_t i) const
2376 {
2377 UG_ASSERT(i < nsh, "Wrong index.");
2378 }
2379
2381 inline void check_multi_index(const MathVector<dim,int>& ind) const
2382 {
2383 UG_ASSERT(ind[0] <= (int)p && ind[0] >= 0, "Wrong Multiindex.");
2384 UG_ASSERT(ind[1] <= (int)p && ind[1] >= 0, "Wrong Multiindex.");
2385 UG_ASSERT(ind[2] <= (int)p && ind[2] >= 0, "Wrong Multiindex.");
2386 }
2387
2388 private:
2390 size_t p;
2391
2393 size_t nsh;
2394
2395 std::vector<Polynomial1D> m_vPolynom;
2396 std::vector<Polynomial1D> m_vDPolynom;
2397
2398 std::vector<MathVector<dim,int> > m_vMultiIndex;
2399};
2400
2402// Octahedron
2404
2405// NOTE: Currently only 1st order is implemented. There is no shape function
2406// set for octahedrons, that is continuous and allows a continuous
2407// derivative in the inner of the pyramid. This is basically, since
2408// one regards the octahedron as 4 tetrahedrons, glued together.
2409template <int TOrder>
2411 : public LagrangeLDS<ReferenceOctahedron>,
2412 public BaseLSFS<LagrangeLSFS<ReferenceOctahedron, TOrder>, 3>
2413{
2414 private:
2416 static const size_t p = TOrder;
2417
2420
2421 public:
2424
2427
2428 public:
2430 static const size_t order = TOrder;
2431
2433 static const int dim = 3; //reference_element_type::dim; (compile error on OSX 10.5)
2434
2436 static const size_t nsh = 6;
2437
2438 public:
2440 LagrangeLSFS();
2441
2443 inline bool continuous() const {return true;}
2444
2446 inline size_t num_sh() const {return nsh;}
2447
2449 inline bool position(size_t i, MathVector<dim>& pos) const
2450 {
2451 // get Multi Index
2452 MathVector<dim,int> ind = multi_index(i);
2453
2454 // set position
2455 for(int d = 0; d < dim; ++d)
2456 pos[d] = EquidistantLagrange1D::position(ind[d], p);
2457
2458 return true;
2459 }
2460
2462 inline number shape(const size_t i, const MathVector<dim>& x) const
2463 {
2464 // only first order
2465 if(p != 1) UG_THROW("Only 1. order Lagrange Octahedron implemented.");
2466
2467 // shape analogously to pyramidal case introducing additional distinction of cases
2468 // z >= 0 and z < 0
2469 const number z_sgn = (x[2] < 0) ? -1.0 : 1.0;
2470
2471 switch(i)
2472 {
2473 case 0 :
2474 if (x[2] < 0)
2475 return(-1.0*x[2]);
2476 else
2477 return(0.0);
2478 case 1 :
2479 if (x[0] > x[1])
2480 return((1.0-x[0])*(1.0-x[1]) + z_sgn*x[2]*(x[1]-1.0));
2481 else
2482 return((1.0-x[0])*(1.0-x[1]) + z_sgn*x[2]*(x[0]-1.0));
2483 case 2 :
2484 if (x[0] > x[1])
2485 return(x[0]*(1.0-x[1]) - z_sgn*x[2]*x[1]);
2486 else
2487 return(x[0]*(1.0-x[1]) - z_sgn*x[2]*x[0]);
2488 case 3 :
2489 if (x[0] > x[1])
2490 return(x[0]*x[1] + z_sgn*x[2]*x[1]);
2491 else
2492 return(x[0]*x[1] + z_sgn*x[2]*x[0]);
2493 case 4 :
2494 if (x[0] > x[1])
2495 return((1.0-x[0])*x[1] - z_sgn*x[2]*x[1]);
2496 else
2497 return((1.0-x[0])*x[1] - z_sgn*x[2]*x[0]);
2498 case 5 :
2499 if (x[2] < 0)
2500 return(0.0);
2501 else
2502 return(x[2]);
2503 default: UG_THROW("Wrong index "<< i<<" in Octahedron.");
2504 }
2505 }
2506
2508 inline number shape(const MathVector<dim,int>& ind, const MathVector<dim>& x) const
2509 {
2510 check_multi_index(ind);
2511
2512 // forward
2513 return shape(index(ind), x);
2514 }
2515
2517 inline void grad(grad_type& g, const size_t i, const MathVector<dim>& x) const
2518 {
2519 // only first order
2520 if(p != 1) UG_THROW("Only 1. order Lagrange Octahedron implemented.");
2521
2522 // shape analogously to pyramidal case introducing additional distinction of cases
2523 // z >= 0 and z < 0
2524 const number z_sgn = (x[2] < 0) ? -1.0 : 1.0;
2525
2526 switch(i)
2527 {
2528 case 0:
2529 if (x[2] < 0.0)
2530 {
2531 g[0] = 0.0;
2532 g[1] = 0.0;
2533 g[2] = -1.0;
2534 break;
2535 }
2536 else
2537 {
2538 g[0] = 0.0;
2539 g[1] = 0.0;
2540 g[2] = 0.0;
2541 break;
2542 }
2543 case 1:
2544 if (x[0] > x[1])
2545 {
2546 g[0] = -(1.0-x[1]);
2547 g[1] = -(1.0-x[0]) + z_sgn*x[2];
2548 g[2] = -z_sgn*(1.0-x[1]);
2549 break;
2550 }
2551 else
2552 {
2553 g[0] = -(1.0-x[1]) + z_sgn*x[2];
2554 g[1] = -(1.0-x[0]);
2555 g[2] = -z_sgn*(1.0-x[0]);
2556 break;
2557 }
2558 case 2:
2559 if (x[0] > x[1])
2560 {
2561 g[0] = (1.0-x[1]);
2562 g[1] = -x[0] - z_sgn*x[2];
2563 g[2] = -z_sgn*x[1];
2564 break;
2565 }
2566 else
2567 {
2568 g[0] = (1.0-x[1]) - z_sgn*x[2];
2569 g[1] = -x[0];
2570 g[2] = -z_sgn*x[0];
2571 break;
2572 }
2573 case 3:
2574 if (x[0] > x[1])
2575 {
2576 g[0] = x[1];
2577 g[1] = x[0] + z_sgn*x[2];
2578 g[2] = z_sgn*x[1];
2579 break;
2580 }
2581 else
2582 {
2583 g[0] = x[1] + z_sgn*x[2];
2584 g[1] = x[0];
2585 g[2] = z_sgn*x[0];
2586 break;
2587 }
2588 case 4:
2589 if (x[0] > x[1])
2590 {
2591 g[0] = -x[1];
2592 g[1] = 1.0-x[0] - z_sgn*x[2];
2593 g[2] = -z_sgn*x[1];
2594 break;
2595 }
2596 else
2597 {
2598 g[0] = -x[1] - z_sgn*x[2];
2599 g[1] = 1.0-x[0];
2600 g[2] = -z_sgn*x[0];
2601 break;
2602 }
2603 case 5:
2604 if (x[2] < 0.0)
2605 {
2606 g[0] = 0.0;
2607 g[1] = 0.0;
2608 g[2] = 0.0;
2609 break;
2610 }
2611 else
2612 {
2613 g[0] = 0.0;
2614 g[1] = 0.0;
2615 g[2] = 1.0;
2616 break;
2617 }
2618 default: UG_THROW("Wrong index "<< i<<" in Octahedron.");
2619 }
2620 }
2621
2623 inline void grad(grad_type& g, const MathVector<dim,int> ind,
2624 const MathVector<dim>& x) const
2625 {
2626 grad(g, index(ind), x);
2627 }
2628
2630 inline const MathVector<dim,int>& multi_index(size_t i) const
2631 {
2632 check_index(i);
2633 return m_vMultiIndex[i];
2634 }
2635
2637 inline size_t index(const MathVector<dim,int>& ind) const
2638 {
2639 check_multi_index(ind);
2640 for(size_t i=0; i<nsh; ++i)
2641 if(multi_index(i) == ind) return i;
2642 UG_THROW("Index not found in LagrangeLSFS");
2643 }
2644
2646 inline void check_index(size_t i) const
2647 {
2648 UG_ASSERT(i < nsh, "Wrong index.");
2649 }
2650
2652 inline void check_multi_index(const MathVector<dim,int>& ind) const
2653 {
2654 UG_ASSERT(ind[0] <= (int)p-ind[2] && ind[0] >= 0, "Wrong Multiindex.");
2655 UG_ASSERT(ind[1] <= (int)p-ind[2] && ind[1] >= 0, "Wrong Multiindex.");
2656 UG_ASSERT(ind[2] <= (int)p && ind[2] >= 0, "Wrong Multiindex.");
2657 }
2658
2659 private:
2660
2661 MathVector<dim,int> m_vMultiIndex[nsh];
2662};
2663
2664
2665} //namespace ug
2666
2667#endif /* __H__UG__LIB_DISC__LOCAL_SHAPE_FUNCTION_SET__LAGRANGE__LAGRANGE__ */
2668
parameterString p
static interface for trial spaces
Definition local_shape_function_set.h:176
number shape_type
Shape type.
Definition local_shape_function_set.h:185
static number position(const size_t i, const size_t degree)
returns the position of the i'th interpolation point
Definition lagrange1d.h:127
size_t mapped_index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:360
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition lagrange.h:337
size_t nsh
Number of shape functions.
Definition lagrange.h:383
MathVector< dim, int > mapped_multi_index(size_t i) const
return Multi index for index i
Definition lagrange.h:353
size_t p
order
Definition lagrange.h:380
shape_type shape(size_t i, const MathVector< dim > &x) const
evaluates the shape function
Definition lagrange.h:325
size_t num_sh() const
Definition lagrange.h:315
void grad(grad_type &g, size_t i, const MathVector< dim > &x) const
evaluates the gradient of the shape function
Definition lagrange.h:331
std::vector< Polynomial1D > m_vPolynom
Shape Polynomials.
Definition lagrange.h:385
void check_index(size_t i) const
checks in debug mode that index is valid
Definition lagrange.h:367
std::vector< Polynomial1D > m_vDPolynom
Derivative of Shape Polynomial.
Definition lagrange.h:386
size_t index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:344
void check_multi_index(const MathVector< dim, int > &ind) const
checks in debug mode that multi-index is valid
Definition lagrange.h:373
std::vector< MathVector< dim, int > > m_vMultiIndex
Definition lagrange.h:388
bool position(size_t i, MathVector< dim > &pos) const
local position of DoF i
Definition lagrange.h:318
FlexLagrangeLSFS(size_t order)
Constructor.
Definition lagrange.h:306
FlexLagrangeLSFS()
default Constructor
Definition lagrange.h:303
bool continuous() const
returns if space constructs continuous functions
Definition lagrange.h:312
size_t nsh
Number of shape functions.
Definition lagrange.h:2393
void check_multi_index(const MathVector< dim, int > &ind) const
checks in debug mode that multi-index is valid
Definition lagrange.h:2381
size_t num_sh() const
Definition lagrange.h:2280
size_t mapped_index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:2359
void grad(grad_type &g, const size_t i, const MathVector< dim > &x) const
evaluates the gradient of the shape function
Definition lagrange.h:2314
void check_index(size_t i) const
checks in debug mode that index is valid
Definition lagrange.h:2375
FlexLagrangeLSFS()
default Constructor
Definition lagrange.h:2268
void grad(grad_type &g, const MathVector< dim, int > ind, const MathVector< dim > &x) const
evaluates the gradient
Definition lagrange.h:2320
bool position(size_t i, MathVector< dim > &pos) const
local position of DoF i
Definition lagrange.h:2283
number shape(const size_t i, const MathVector< dim > &x) const
evaluates the shape function
Definition lagrange.h:2296
FlexLagrangeLSFS(size_t order)
Constructor.
Definition lagrange.h:2271
number shape(const MathVector< dim, int > &ind, const MathVector< dim > &x) const
shape value for a Multi Index
Definition lagrange.h:2303
std::vector< MathVector< dim, int > > m_vMultiIndex
Definition lagrange.h:2398
bool continuous() const
returns if space constructs continuous functions
Definition lagrange.h:2277
std::vector< Polynomial1D > m_vDPolynom
Derivative of Shape Polynomial.
Definition lagrange.h:2396
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition lagrange.h:2343
std::vector< Polynomial1D > m_vPolynom
Shape Polynomials.
Definition lagrange.h:2395
MathVector< dim, int > mapped_multi_index(size_t i) const
return the multi_index for an index
Definition lagrange.h:2367
size_t p
order
Definition lagrange.h:2390
size_t index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:2350
bool position(size_t i, MathVector< dim > &pos) const
local position of DoF i
Definition lagrange.h:1701
number shape(const MathVector< dim, int > &ind, const MathVector< dim > &x) const
shape value for a Multi Index
Definition lagrange.h:1723
MathVector< dim, int > mapped_multi_index(size_t i) const
return the multi_index for an index
Definition lagrange.h:1820
size_t mapped_index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:1805
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition lagrange.h:1789
std::vector< Polynomial1D > m_vDPolynom
Definition lagrange.h:1864
std::vector< MathVector< dim, int > > m_vMultiIndex
Definition lagrange.h:1868
size_t index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:1796
std::vector< Polynomial1D > m_vPolynom
Definition lagrange.h:1863
size_t num_sh() const
Definition lagrange.h:1698
void check_index(size_t i) const
checks in debug mode that index is valid
Definition lagrange.h:1839
void grad(grad_type &g, const size_t i, const MathVector< dim > &x) const
evaluates the gradient of the shape function
Definition lagrange.h:1741
std::vector< Polynomial1D > m_vDTruncPolynom
Definition lagrange.h:1866
size_t nsh
Number of shape functions.
Definition lagrange.h:1858
FlexLagrangeLSFS(size_t order)
Constructor.
Definition lagrange.h:1689
bool continuous() const
returns if space constructs continuous functions
Definition lagrange.h:1695
void grad(grad_type &g, const MathVector< dim, int > ind, const MathVector< dim > &x) const
evaluates the gradient
Definition lagrange.h:1747
size_t p
order
Definition lagrange.h:1855
void check_multi_index(const MathVector< dim, int > &ind) const
checks in debug mode that multi-index is valid
Definition lagrange.h:1845
FlexLagrangeLSFS()
default Constructor
Definition lagrange.h:1686
number shape(const size_t i, const MathVector< dim > &x) const
evaluates the shape function
Definition lagrange.h:1716
size_t dofPerLayer
number of dofs per layer
Definition lagrange.h:1861
std::vector< Polynomial1D > m_vTruncPolynom
Definition lagrange.h:1865
size_t index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:999
bool position(size_t i, MathVector< dim > &pos) const
local position of DoF i
Definition lagrange.h:933
void check_multi_index(const MathVector< dim, int > &ind) const
checks in debug mode that multi-index is valid
Definition lagrange.h:1030
void check_index(size_t i) const
checks in debug mode that index is valid
Definition lagrange.h:1024
size_t nsh
Number of shape functions.
Definition lagrange.h:1041
std::vector< MathVector< dim, int > > m_vMultiIndex
Definition lagrange.h:1046
void grad(grad_type &g, const MathVector< dim, int > ind, const MathVector< dim > &x) const
evaluates the gradient
Definition lagrange.h:969
FlexLagrangeLSFS(size_t order)
Constructor.
Definition lagrange.h:921
number shape(const size_t i, const MathVector< dim > &x) const
evaluates the shape function
Definition lagrange.h:946
std::vector< Polynomial1D > m_vDPolynom
Derivative of Shape Polynomial.
Definition lagrange.h:1044
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition lagrange.h:992
MathVector< dim, int > mapped_multi_index(size_t i) const
return the multi_index for an index
Definition lagrange.h:1016
size_t mapped_index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:1008
void grad(grad_type &g, const size_t i, const MathVector< dim > &x) const
evaluates the gradient of the shape function
Definition lagrange.h:963
FlexLagrangeLSFS()
default Constructor
Definition lagrange.h:918
bool continuous() const
returns if space constructs continuous functions
Definition lagrange.h:927
std::vector< Polynomial1D > m_vPolynom
Shape Polynomials.
Definition lagrange.h:1043
size_t num_sh() const
Definition lagrange.h:930
size_t p
order
Definition lagrange.h:1038
number shape(const MathVector< dim, int > &ind, const MathVector< dim > &x) const
shape value for a Multi Index
Definition lagrange.h:953
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition lagrange.h:1365
void check_multi_index(const MathVector< dim, int > &ind) const
checks in debug mode that multi-index is valid
Definition lagrange.h:1445
std::vector< Polynomial1D > m_vPolynom
Shape Polynomials.
Definition lagrange.h:1460
bool continuous() const
returns if space constructs continuous functions
Definition lagrange.h:1284
size_t p
order
Definition lagrange.h:1455
void check_index(size_t i) const
checks in debug mode that index is valid
Definition lagrange.h:1439
FlexLagrangeLSFS()
default Constructor
Definition lagrange.h:1275
number shape(const size_t i, const MathVector< dim > &x) const
evaluates the shape function
Definition lagrange.h:1303
size_t mapped_index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:1381
size_t num_sh() const
Definition lagrange.h:1287
std::vector< MathVector< dim, int > > m_vMultiIndex
Definition lagrange.h:1463
MathVector< dim, int > mapped_multi_index(size_t i) const
return the multi_index for an index
Definition lagrange.h:1401
std::vector< Polynomial1D > m_vDPolynom
Derivative of Shape Polynomial.
Definition lagrange.h:1461
void grad(grad_type &g, const size_t i, const MathVector< dim > &x) const
evaluates the gradient of the shape function
Definition lagrange.h:1326
number shape(const MathVector< dim, int > &ind, const MathVector< dim > &x) const
shape value for a Multi Index
Definition lagrange.h:1310
size_t nsh
Number of shape functions.
Definition lagrange.h:1458
bool position(size_t i, MathVector< dim > &pos) const
local position of DoF i
Definition lagrange.h:1290
void grad(grad_type &g, const MathVector< dim, int > ind, const MathVector< dim > &x) const
evaluates the gradient
Definition lagrange.h:1332
FlexLagrangeLSFS(size_t order)
Constructor.
Definition lagrange.h:1278
size_t index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:1372
size_t index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:686
void check_multi_index(const MathVector< dim, int > &ind) const
checks in debug mode that multi-index is valid
Definition lagrange.h:732
size_t nsh
Number of shape functions.
Definition lagrange.h:744
FlexLagrangeLSFS(size_t order)
Constructor.
Definition lagrange.h:592
bool continuous() const
returns if space constructs continuous functions
Definition lagrange.h:598
number shape(const size_t i, const MathVector< dim > &x) const
evaluates the shape function
Definition lagrange.h:617
size_t mapped_index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:695
void check_index(size_t i) const
checks in debug mode that index is valid
Definition lagrange.h:726
number shape(const MathVector< dim, int > &ind, const MathVector< dim > &x) const
shape value for a Multi Index
Definition lagrange.h:624
MathVector< dim, int > mapped_multi_index(size_t i) const
return the multi_index for an index
Definition lagrange.h:708
std::vector< Polynomial1D > m_vDPolynom
Derivative of Shape Polynomial.
Definition lagrange.h:747
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition lagrange.h:679
std::vector< Polynomial1D > m_vPolynom
Shape Polynomials.
Definition lagrange.h:746
void grad(grad_type &g, const size_t i, const MathVector< dim > &x) const
evaluates the shape function
Definition lagrange.h:640
bool position(size_t i, MathVector< dim > &pos) const
local position of DoF i
Definition lagrange.h:604
size_t p
order
Definition lagrange.h:741
FlexLagrangeLSFS()
default Constructor
Definition lagrange.h:589
void grad(grad_type &g, const MathVector< dim, int > ind, const MathVector< dim > &x) const
evaluates the gradient
Definition lagrange.h:646
std::vector< MathVector< dim, int > > m_vMultiIndex
Definition lagrange.h:749
size_t num_sh() const
Definition lagrange.h:601
void grad(grad_type &g, size_t i, const MathVector< dim > &x) const
evaluates the gradient of the shape function
Definition lagrange.h:160
FlexLagrangeLSFS()
default Constructor
Definition lagrange.h:136
size_t p
order
Definition lagrange.h:166
bool continuous() const
returns if space constructs continuous functions
Definition lagrange.h:142
shape_type shape(size_t i, const MathVector< dim > &x) const
evaluates the shape function
Definition lagrange.h:154
FlexLagrangeLSFS(size_t order)
Constructor.
Definition lagrange.h:139
bool position(size_t i, MathVector< dim > &pos) const
local position of DoF i
Definition lagrange.h:148
size_t num_sh() const
Definition lagrange.h:145
Lagrange Shape Function Set without virtual functions and flexible order.
Definition lagrange.h:52
Lagrange DoF Set.
Definition lagrange_local_dof.h:55
bool continuous() const
returns if space constructs continuous functions
Definition lagrange.h:215
shape_type shape(size_t i, const MathVector< dim > &x) const
evaluates the shape function
Definition lagrange.h:228
base_type::shape_type shape_type
Shape type.
Definition lagrange.h:195
BaseLSFS< LagrangeLSFS< ReferenceEdge, TOrder >, 1 > base_type
base class
Definition lagrange.h:191
void grad(grad_type &g, size_t i, const MathVector< dim > &x) const
evaluates the gradient of the shape function
Definition lagrange.h:234
size_t num_sh() const
Definition lagrange.h:218
base_type::grad_type grad_type
Gradient type.
Definition lagrange.h:198
size_t index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:247
bool position(size_t i, MathVector< dim > &pos) const
local position of DoF i
Definition lagrange.h:221
void check_multi_index(const MathVector< dim, int > &ind) const
checks in debug mode that multi-index is valid
Definition lagrange.h:276
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition lagrange.h:240
size_t mapped_index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:263
MathVector< dim, int > mapped_multi_index(size_t i) const
return Multi index for index i
Definition lagrange.h:256
void check_index(size_t i) const
checks in debug mode that index is valid
Definition lagrange.h:270
void grad(grad_type &g, const size_t i, const MathVector< dim > &x) const
evaluates the gradient of the shape function
Definition lagrange.h:2176
void check_multi_index(const MathVector< dim, int > &ind) const
checks in debug mode that multi-index is valid
Definition lagrange.h:2243
void grad(grad_type &g, const MathVector< dim, int > ind, const MathVector< dim > &x) const
evaluates the gradient
Definition lagrange.h:2182
size_t num_sh() const
Definition lagrange.h:2142
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition lagrange.h:2205
BaseLSFS< LagrangeLSFS< ReferenceHexahedron, TOrder >, 3 > base_type
base class
Definition lagrange.h:2115
number shape(const MathVector< dim, int > &ind, const MathVector< dim > &x) const
shape value for a Multi Index
Definition lagrange.h:2165
MathVector< dim, int > mapped_multi_index(size_t i) const
return the multi_index for an index
Definition lagrange.h:2229
bool position(size_t i, MathVector< dim > &pos) const
local position of DoF i
Definition lagrange.h:2145
number shape(const size_t i, const MathVector< dim > &x) const
evaluates the shape function
Definition lagrange.h:2158
void check_index(size_t i) const
checks in debug mode that index is valid
Definition lagrange.h:2237
base_type::shape_type shape_type
Shape type.
Definition lagrange.h:2119
size_t mapped_index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:2221
bool continuous() const
returns if space constructs continuous functions
Definition lagrange.h:2139
base_type::grad_type grad_type
Gradient type.
Definition lagrange.h:2122
size_t index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:2212
number shape(const MathVector< dim, int > &ind, const MathVector< dim > &x) const
shape value for a Multi Index
Definition lagrange.h:2508
void grad(grad_type &g, const MathVector< dim, int > ind, const MathVector< dim > &x) const
evaluates the gradient
Definition lagrange.h:2623
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition lagrange.h:2630
void check_multi_index(const MathVector< dim, int > &ind) const
checks in debug mode that multi-index is valid
Definition lagrange.h:2652
size_t index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:2637
size_t num_sh() const
Definition lagrange.h:2446
base_type::shape_type shape_type
Shape type.
Definition lagrange.h:2423
void grad(grad_type &g, const size_t i, const MathVector< dim > &x) const
evaluates the gradient of the shape function
Definition lagrange.h:2517
base_type::grad_type grad_type
Gradient type.
Definition lagrange.h:2426
bool continuous() const
returns if space constructs continuous functions
Definition lagrange.h:2443
void check_index(size_t i) const
checks in debug mode that index is valid
Definition lagrange.h:2646
BaseLSFS< LagrangeLSFS< ReferenceOctahedron, TOrder >, 3 > base_type
base class
Definition lagrange.h:2419
number shape(const size_t i, const MathVector< dim > &x) const
evaluates the shape function
Definition lagrange.h:2462
bool position(size_t i, MathVector< dim > &pos) const
local position of DoF i
Definition lagrange.h:2449
BaseLSFS< LagrangeLSFS< ReferencePrism, TOrder >, 3 > base_type
base class
Definition lagrange.h:1483
void grad(grad_type &g, const MathVector< dim, int > ind, const MathVector< dim > &x) const
evaluates the gradient
Definition lagrange.h:1559
MathVector< dim, int > mapped_multi_index(size_t i) const
return the multi_index for an index
Definition lagrange.h:1632
size_t index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:1608
bool continuous() const
returns if space constructs continuous functions
Definition lagrange.h:1507
number shape(const MathVector< dim, int > &ind, const MathVector< dim > &x) const
shape value for a Multi Index
Definition lagrange.h:1535
size_t num_sh() const
Definition lagrange.h:1510
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition lagrange.h:1601
size_t mapped_index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:1617
void check_index(size_t i) const
checks in debug mode that index is valid
Definition lagrange.h:1651
base_type::grad_type grad_type
Gradient type.
Definition lagrange.h:1490
void grad(grad_type &g, const size_t i, const MathVector< dim > &x) const
evaluates the gradient of the shape function
Definition lagrange.h:1553
bool position(size_t i, MathVector< dim > &pos) const
local position of DoF i
Definition lagrange.h:1513
number shape(const size_t i, const MathVector< dim > &x) const
evaluates the shape function
Definition lagrange.h:1528
base_type::shape_type shape_type
Shape type.
Definition lagrange.h:1487
void check_multi_index(const MathVector< dim, int > &ind) const
checks in debug mode that multi-index is valid
Definition lagrange.h:1657
void grad(grad_type &g, const size_t i, const MathVector< dim > &x) const
evaluates the gradient of the shape function
Definition lagrange.h:1976
MathVector< dim, int > mapped_multi_index(size_t i) const
return the multi_index for an index
Definition lagrange.h:2062
void check_index(size_t i) const
checks in debug mode that index is valid
Definition lagrange.h:2081
size_t index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:2035
void grad(grad_type &g, const MathVector< dim, int > ind, const MathVector< dim > &x) const
evaluates the gradient
Definition lagrange.h:2021
void check_multi_index(const MathVector< dim, int > &ind) const
checks in debug mode that multi-index is valid
Definition lagrange.h:2087
size_t num_sh() const
Definition lagrange.h:1929
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition lagrange.h:2028
bool position(size_t i, MathVector< dim > &pos) const
local position of DoF i
Definition lagrange.h:1932
bool continuous() const
returns if space constructs continuous functions
Definition lagrange.h:1926
std::vector< std::vector< Polynomial1D > > m_vvPolynom
Definition lagrange.h:2095
std::vector< std::vector< Polynomial1D > > m_vvDPolynom
Definition lagrange.h:2096
number shape(const size_t i, const MathVector< dim > &x) const
evaluates the shape function
Definition lagrange.h:1945
size_t mapped_index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:2044
BaseLSFS< LagrangeLSFS< ReferencePyramid, TOrder >, 3 > base_type
base class
Definition lagrange.h:1902
number shape(const MathVector< dim, int > &ind, const MathVector< dim > &x) const
shape value for a Multi Index
Definition lagrange.h:1966
base_type::shape_type shape_type
Shape type.
Definition lagrange.h:1906
base_type::grad_type grad_type
Gradient type.
Definition lagrange.h:1909
void grad(grad_type &g, const size_t i, const MathVector< dim > &x) const
evaluates the gradient of the shape function
Definition lagrange.h:826
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition lagrange.h:855
bool continuous() const
returns if space constructs continuous functions
Definition lagrange.h:790
void check_index(size_t i) const
checks in debug mode that index is valid
Definition lagrange.h:887
size_t index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:862
BaseLSFS< LagrangeLSFS< ReferenceQuadrilateral, TOrder >, 2 > base_type
base class
Definition lagrange.h:766
MathVector< dim, int > mapped_multi_index(size_t i) const
return the multi_index for an index
Definition lagrange.h:879
size_t num_sh() const
Definition lagrange.h:793
base_type::grad_type grad_type
Gradient type.
Definition lagrange.h:773
void grad(grad_type &g, const MathVector< dim, int > ind, const MathVector< dim > &x) const
evaluates the gradient
Definition lagrange.h:832
number shape(const size_t i, const MathVector< dim > &x) const
evaluates the shape function
Definition lagrange.h:809
size_t mapped_index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:871
base_type::shape_type shape_type
Shape type.
Definition lagrange.h:770
number shape(const MathVector< dim, int > &ind, const MathVector< dim > &x) const
shape value for a Multi Index
Definition lagrange.h:816
bool position(size_t i, MathVector< dim > &pos) const
local position of DoF i
Definition lagrange.h:796
void check_multi_index(const MathVector< dim, int > &ind) const
checks in debug mode that multi-index is valid
Definition lagrange.h:893
bool continuous() const
returns if space constructs continuous functions
Definition lagrange.h:1087
base_type::grad_type grad_type
Gradient type.
Definition lagrange.h:1070
bool position(size_t i, MathVector< dim > &pos) const
local position of DoF i
Definition lagrange.h:1093
void check_index(size_t i) const
checks in debug mode that index is valid
Definition lagrange.h:1242
size_t num_sh() const
Definition lagrange.h:1090
BaseLSFS< LagrangeLSFS< ReferenceTetrahedron, TOrder >, 3 > base_type
base class
Definition lagrange.h:1063
void check_multi_index(const MathVector< dim, int > &ind) const
checks in debug mode that multi-index is valid
Definition lagrange.h:1248
base_type::shape_type shape_type
Shape type.
Definition lagrange.h:1067
number shape(const size_t i, const MathVector< dim > &x) const
evaluates the shape function
Definition lagrange.h:1106
MathVector< dim, int > mapped_multi_index(size_t i) const
return the multi_index for an index
Definition lagrange.h:1204
size_t index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:1175
void grad(grad_type &g, const size_t i, const MathVector< dim > &x) const
evaluates the gradient of the shape function
Definition lagrange.h:1129
number shape(const MathVector< dim, int > &ind, const MathVector< dim > &x) const
shape value for a Multi Index
Definition lagrange.h:1113
void grad(grad_type &g, const MathVector< dim, int > ind, const MathVector< dim > &x) const
evaluates the gradient
Definition lagrange.h:1135
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition lagrange.h:1168
size_t mapped_index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:1184
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition lagrange.h:510
size_t num_sh() const
Definition lagrange.h:432
base_type::grad_type grad_type
Gradient type.
Definition lagrange.h:412
number shape(const MathVector< dim, int > &ind, const MathVector< dim > &x) const
shape value for a Multi Index
Definition lagrange.h:455
void check_index(size_t i) const
checks in debug mode that index is valid
Definition lagrange.h:557
size_t mapped_index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:526
void grad(grad_type &g, const MathVector< dim, int > ind, const MathVector< dim > &x) const
evaluates the gradient
Definition lagrange.h:477
size_t index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition lagrange.h:517
bool position(size_t i, MathVector< dim > &pos) const
local position of DoF i
Definition lagrange.h:435
base_type::shape_type shape_type
Shape type.
Definition lagrange.h:409
void grad(grad_type &g, const size_t i, const MathVector< dim > &x) const
evaluates the shape function
Definition lagrange.h:471
number shape(const size_t i, const MathVector< dim > &x) const
evaluates the shape function
Definition lagrange.h:448
void check_multi_index(const MathVector< dim, int > &ind) const
checks in debug mode that multi-index is valid
Definition lagrange.h:563
MathVector< dim, int > mapped_multi_index(size_t i) const
return the multi_index for an index
Definition lagrange.h:539
BaseLSFS< LagrangeLSFS< ReferenceTriangle, TOrder >, 2 > base_type
base class
Definition lagrange.h:405
bool continuous() const
returns if space constructs continuous functions
Definition lagrange.h:429
bool continuous() const
returns if space constructs continuous functions
Definition lagrange.h:98
bool position(size_t i, MathVector< dim > &pos) const
local position of DoF i
Definition lagrange.h:104
size_t num_sh() const
Definition lagrange.h:101
base_type::grad_type grad_type
Gradient type.
Definition lagrange.h:81
void grad(grad_type &g, size_t i, const MathVector< dim > &x) const
evaluates the gradient of the shape function
Definition lagrange.h:116
shape_type shape(size_t i, const MathVector< dim > &x) const
evaluates the shape function
Definition lagrange.h:110
base_type::shape_type shape_type
Shape type.
Definition lagrange.h:78
BaseLSFS< LagrangeLSFS< ReferenceVertex, TOrder >, 0 > base_type
base class
Definition lagrange.h:74
LagrangeLSFS()
Constructor.
Definition lagrange.h:95
Lagrange Shape Function Set without virtual functions and fixed order.
Definition lagrange.h:48
a mathematical Vector with N entries.
Definition math_vector.h:97
Definition polynomial1d.h:51
Definition reference_element.h:345
static const int dim
dimension of reference element
Definition reference_element.h:351
reference element for a hexahedron
Definition reference_element.h:648
static const int dim
dimension of reference element
Definition reference_element.h:654
Definition reference_element.h:699
Definition reference_element.h:595
static const int dim
dimension of reference element
Definition reference_element.h:601
Definition reference_element.h:546
Definition reference_element.h:445
static const int dim
dimension of reference element
Definition reference_element.h:451
Definition reference_element.h:494
static const int dim
dimension of reference element
Definition reference_element.h:500
Definition reference_element.h:394
static const int dim
dimension of reference element
Definition reference_element.h:400
Definition reference_element.h:303
static const int dim
dimension of reference element
Definition reference_element.h:309
static number position(const size_t i, const size_t degree)
returns the position of the i'th interpolation point
Definition lagrange1d.h:191
#define UG_ASSERT(expr, msg)
Definition assert.h:70
#define UG_THROW(msg)
Definition error.h:57
double number
Definition types.h:124
int BinomCoeff(int n, int k)
Returns the BinomialCoefficient.
Definition math_util.cpp:553
the ug namespace
const number SMALL
Definition math_constants.h:41
Definition metaprogramming_util.h:188