ug4
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 
44 namespace ug{
45 
47 template <typename TRefElem, int TOrder>
49 
51 template <typename TRefElem>
53 
54 
56 // Vertex
58 
60 
64 template <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 
81  typedef typename base_type::grad_type grad_type;
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 
125 template <>
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 
181 template <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 
198  typedef typename base_type::grad_type grad_type;
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 
292 template <>
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 
395 template <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 
412  typedef typename base_type::grad_type grad_type;
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 
578 template <>
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 
756 template <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 
773  typedef typename base_type::grad_type grad_type;
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 
907 template <>
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 
1053 template <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 
1080  static const size_t nsh = BinomialCoefficient<dim + p, p>::value;
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)
1100  pos[d] = TruncatedEquidistantLagrange1D::position(ind[d], p);
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 
1264 template <>
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)
1297  pos[d] = TruncatedEquidistantLagrange1D::position(ind[d], p);
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 
1470 template <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)
1520  pos[d] = TruncatedEquidistantLagrange1D::position(ind[d], p);
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 
1559  void grad(grad_type& g, const MathVector<dim,int> ind,
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 
1675 template <>
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)
1708  pos[d] = TruncatedEquidistantLagrange1D::position(ind[d], p);
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 
1747  void grad(grad_type& g, const MathVector<dim,int> ind,
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 
1861  size_t dofPerLayer;
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 
1875 namespace {
1876 template <int p>
1877 struct NumberOfDoFsOfPyramid{
1878  enum{value = NumberOfDoFsOfPyramid<p-1>::value + (p+1)*(p+1)};
1879 };
1880 
1881 // specialization to end recursion
1882 template <> struct NumberOfDoFsOfPyramid<1>{enum {value = 5};};
1883 template <> struct NumberOfDoFsOfPyramid<0>{enum {value = 0};};
1884 template <> 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.
1892 template <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 
2105 template <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 
2257 template <>
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.
2409 template <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
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
MathVector< dim, int > mapped_multi_index(size_t i) const
return Multi index for index i
Definition: lagrange.h:353
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
MathVector< dim, int > mapped_multi_index(size_t i) const
return the multi_index for an index
Definition: lagrange.h:2367
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
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
size_t mapped_index(const MathVector< dim, int > &ind) const
return the index for a multi_index
Definition: lagrange.h:1805
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
MathVector< dim, int > mapped_multi_index(size_t i) const
return the multi_index for an index
Definition: lagrange.h:1820
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
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition: lagrange.h:1789
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
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
MathVector< dim, int > mapped_multi_index(size_t i) const
return the multi_index for an index
Definition: lagrange.h:1016
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:992
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
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition: lagrange.h:1365
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
std::vector< Polynomial1D > m_vDPolynom
Derivative of Shape Polynomial.
Definition: lagrange.h:747
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
MathVector< dim, int > mapped_multi_index(size_t i) const
return the multi_index for an index
Definition: lagrange.h:708
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
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition: lagrange.h:679
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
MathVector< dim, int > mapped_multi_index(size_t i) const
return Multi index for index i
Definition: lagrange.h:256
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
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
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
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
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition: lagrange.h:2205
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
MathVector< dim, int > mapped_multi_index(size_t i) const
return the multi_index for an index
Definition: lagrange.h:2229
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
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
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition: lagrange.h:2630
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
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
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
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition: lagrange.h:1601
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
MathVector< dim, int > mapped_multi_index(size_t i) const
return the multi_index for an index
Definition: lagrange.h:1632
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
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition: lagrange.h:2028
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
bool position(size_t i, MathVector< dim > &pos) const
local position of DoF i
Definition: lagrange.h:1932
MathVector< dim, int > mapped_multi_index(size_t i) const
return the multi_index for an index
Definition: lagrange.h:2062
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
MathVector< dim, int > mapped_multi_index(size_t i) const
return the multi_index for an index
Definition: lagrange.h:879
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
bool continuous() const
returns if space constructs continuous functions
Definition: lagrange.h:790
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition: lagrange.h:855
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
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
const MathVector< dim, int > & multi_index(size_t i) const
return Multi index for index i
Definition: lagrange.h:1168
void check_index(size_t i) const
checks in debug mode that index is valid
Definition: lagrange.h:1242
MathVector< dim, int > mapped_multi_index(size_t i) const
return the multi_index for an index
Definition: lagrange.h:1204
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
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
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
static const int dim
#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