LCOV - code coverage report
Current view: top level - ugbase/lib_disc/local_finite_element/lagrange - lagrange.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 54.5 % 211 115
Test Date: 2025-09-21 23:31:46 Functions: 64.2 % 67 43

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2011-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              : #include "lagrange.h"
      34              : #include <sstream>
      35              : #include "common/util/provider.h"
      36              : 
      37              : namespace ug{
      38              : 
      39              : template <typename TRefElem>
      40              : void SetLagrangeVertexMultiIndex(       MathVector<TRefElem::dim,int>* vMultiIndex,
      41              :                                 const TRefElem& rRef,
      42              :                                 size_t p,
      43              :                                 size_t& index)
      44              : {
      45              : //      dimension of Reference element
      46              :         static const int dim = TRefElem::dim;
      47              : 
      48              : //      get corner position integer
      49              :         const MathVector<dim,int>* vCo = rRef.corner();
      50              : 
      51              : //      loop all vertices
      52          105 :         for(size_t i = 0; i< rRef.num(0); ++i)
      53              :         {
      54              :         //      set multi index
      55          299 :                 for(int d = 0; d<dim; ++d)
      56              :                 {
      57              :                         UG_ASSERT(((long)p)*vCo[i][d] >= 0,
      58              :                                   "Wrong multi index m["<<d<<"]="<<p*vCo[i][d]);
      59          219 :                         vMultiIndex[index][d] = p*vCo[i][d];
      60              :                 }
      61              : 
      62              :         //      next index
      63           86 :                 ++index;
      64              :         }
      65              : }
      66              : 
      67              : template <typename TRefElem>
      68           19 : void SetLagrangeEdgeMultiIndex( MathVector<TRefElem::dim,int>* vMultiIndex,
      69              :                         const TRefElem& rRef,
      70              :                         size_t p,
      71              :                         size_t& index)
      72              : {
      73              : //      dimension of Reference element
      74              :         static const int dim = TRefElem::dim;
      75              : 
      76              : //      only for 2d,3d elems we do something
      77              :         if(dim < 1) return;
      78              : 
      79              : //      get corner position integer
      80              :         const MathVector<dim,int>* vCo = rRef.corner();
      81              : 
      82              : //      loop all edges
      83          132 :         for(size_t e = 0; e< rRef.num(1); ++e)
      84              :         {
      85              :         //      get ids of corners of edge
      86          113 :                 const size_t co0 = rRef.id(1,e, 0,0);
      87          113 :                 const size_t co1 = rRef.id(1,e, 0,1);
      88              : 
      89              :         //      add dofs on the edge
      90          218 :                 for(size_t i = 1; i < p; ++i)
      91              :                 {
      92              :                 //      compute multi index
      93              :                         MathVector<dim,int> m;
      94          105 :                         VecScaleAdd(m, i, vCo[co1], (p-i), vCo[co0]);
      95              : 
      96              :                 //      set multi index
      97          393 :                         for(int d = 0; d<dim; ++d)
      98              :                         {
      99              :                                 UG_ASSERT(m[d] >= 0, "Wrong multi index m["<<d<<"]="<<m[d]);
     100          288 :                                 vMultiIndex[index][d] = m[d];
     101              :                         }
     102              : 
     103              :                 //      next index
     104          105 :                         index++;
     105              :                 }
     106              :         }
     107              : }
     108              : 
     109              : template <typename TRefElem>
     110           16 : void SetLagrangeFaceMultiIndex( MathVector<TRefElem::dim,int>* vMultiIndex,
     111              :                         const TRefElem& rRef,
     112              :                         size_t p,
     113              :                         size_t& index)
     114              : {
     115              : //      dimension of Reference element
     116              :         static const int dim = TRefElem::dim;
     117              : 
     118              : //      only for 2d,3d elems we do something
     119              :         if(dim < 2) return;
     120              : 
     121              : //      get corner position integer
     122              :         const MathVector<dim,int>* vCo = rRef.corner();
     123              : 
     124              : //      add dof on quadrilateral
     125           72 :         for(size_t f = 0; f< rRef.num(2); ++f)
     126              :         {
     127              :         //      get ids of corners of edge
     128              :                 const size_t co0 = rRef.id(2,f, 0,0);
     129           56 :                 const size_t co1 = rRef.id(2,f, 0,1);
     130              :                 size_t co2 = rRef.id(2,f, 0,2);
     131           56 :                 if(rRef.num(2,f,0)==4) co2 = rRef.id(2,f, 0,3);
     132              : 
     133              :         //      directions of counting
     134              :                 MathVector<dim,int> d1, d2;
     135           56 :                 VecSubtract(d1, vCo[co1], vCo[co0]);
     136           56 :                 VecSubtract(d2, vCo[co2], vCo[co0]);
     137              : 
     138              :         //      loop 'y'-direction
     139          107 :                 for(size_t j = 1; j < p; ++j)
     140              :                 {
     141              :                 //      for a quadrilateral we have a quadratic loop, but for a
     142              :                 //      triangle we need to stop at the diagonal
     143           51 :                         const size_t off = ((rRef.num(2,f,0)==3) ? j : 0);
     144              : 
     145              :                 //      loop 'x'-direction
     146          108 :                         for(size_t i = 1; i < p-off; ++i)
     147              :                         {
     148              :                         //      compute multi index
     149           57 :                                 MathVector<dim,int> m = vCo[co0]; m *= p;
     150           57 :                                 VecScaleAppend(m, i, d1, j, d2);
     151              : 
     152              :                         //      set multi index
     153          222 :                                 for(int d = 0; d<dim; ++d)
     154              :                                 {
     155              :                                         UG_ASSERT(m[d] >= 0, "Wrong multi index m["<<d<<"]="<<m[d]);
     156          165 :                                         vMultiIndex[index][d] = m[d];
     157              :                                 }
     158              :                                 
     159              :                         //      next index
     160           57 :                                 ++index;
     161              :                         }
     162              :                 }
     163              :         }
     164              : }
     165              : 
     166              : template <typename TRefElem>
     167           10 : void SetLagrangeVolumeMultiIndex(       MathVector<TRefElem::dim,int>* vMultiIndex,
     168              :                                         const TRefElem& rRef,
     169              :                                         size_t p,
     170              :                                         size_t& index)
     171              : {
     172              : //      dimension of Reference element
     173              :         static const int dim = TRefElem::dim;
     174              : 
     175              : //      only for 3d elems we do something
     176              :         if(dim < 3) return;
     177              : 
     178              : //      get corner position integer
     179              : //      const MathVector<dim,int>* vCo = rRef.corner();
     180              : 
     181              : //      get type of reference element
     182              :         ReferenceObjectID type = rRef.roid(dim, 0);
     183              : 
     184              : //      handle elems
     185           10 :         switch(type)
     186              :         {
     187              :         case ROID_TETRAHEDRON:
     188            6 :                 for(size_t m2 = 1; m2 < p; ++m2)
     189            4 :                         for(size_t m1 = 1; m1 < p-m2; ++m1)
     190            1 :                                 for(size_t m0 = 1; m0 < p-m2-m1; ++m0)
     191              :                                 {
     192              :                                 //      use regular mapping for inner DoFs
     193            0 :                                         vMultiIndex[index][0] = m0;
     194            0 :                                         vMultiIndex[index][1] = m1;
     195            0 :                                         vMultiIndex[index++][2] = m2;
     196              :                                 }
     197              :                 break;
     198              : 
     199            1 :         case ROID_PYRAMID:
     200            1 :                 if(p>1) UG_THROW("LagrangeLSFS: Higher order Pyramid not implemented.");
     201              :                 break;
     202              : 
     203            0 :         case ROID_OCTAHEDRON:
     204            0 :                 if(p>1) UG_THROW("LagrangeLSFS: Higher order Octahedron not implemented.");
     205              :                 break;
     206              : 
     207              :         case ROID_PRISM:
     208            6 :                 for(size_t m2 = 1; m2 < p; ++m2)
     209            8 :                         for(size_t m1 = 1; m1 < p; ++m1)
     210            7 :                                 for(size_t m0 = 1; m0 < p-m1; ++m0)
     211              :                                 {
     212              :                                 //      use regular mapping for inner DoFs
     213            2 :                                         vMultiIndex[index][0] = m0;
     214            2 :                                         vMultiIndex[index][1] = m1;
     215            2 :                                         vMultiIndex[index++][2] = m2;
     216              :                                 }
     217              :                 break;
     218              : 
     219              :         case ROID_HEXAHEDRON:
     220            6 :                 for(size_t m2 = 1; m2 < p; ++m2)
     221            8 :                         for(size_t m1 = 1; m1 < p; ++m1)
     222           14 :                                 for(size_t m0 = 1; m0 < p; ++m0)
     223              :                                 {
     224              :                                 //      use regular mapping for inner DoFs
     225            9 :                                         vMultiIndex[index][0] = m0;
     226            9 :                                         vMultiIndex[index][1] = m1;
     227            9 :                                         vMultiIndex[index++][2] = m2;
     228              :                                 }
     229              :                 break;
     230            0 :         default: UG_THROW("LagrangeLSFS: Missing 3d mapping for type '"<<type<<"'."
     231              :                                 " roid="<<rRef.reference_object_id());
     232              :         }
     233              : }
     234              : 
     235              : template <typename TRefElem>
     236           19 : void SetLagrangeMultiIndex(     MathVector<TRefElem::dim,int>* vMultiIndex,
     237              :                                 const TRefElem& rRef,
     238              :                                 size_t p)
     239              : {
     240              : //      init shape -> multi-index mapping
     241           19 :         size_t index = 0;
     242              : 
     243              : //      vertices
     244              :         SetLagrangeVertexMultiIndex(vMultiIndex, rRef, p, index);
     245              : 
     246              : //      edge
     247           19 :         SetLagrangeEdgeMultiIndex(vMultiIndex, rRef, p, index);
     248              : 
     249              : //      faces
     250           16 :         SetLagrangeFaceMultiIndex(vMultiIndex, rRef, p, index);
     251              : 
     252              : //      volumes
     253           10 :         SetLagrangeVolumeMultiIndex(vMultiIndex, rRef, p, index);
     254           19 : }
     255              : 
     256              : ///////////////////////////////////////////////////////////////////////////////
     257              : // Edge
     258              : ///////////////////////////////////////////////////////////////////////////////
     259              : 
     260              : template <int TOrder>
     261            3 : LagrangeLSFS<ReferenceEdge, TOrder>::LagrangeLSFS()
     262           30 :         : LagrangeLDS<ReferenceEdge>(p)
     263              : {
     264              : //      init polynomials
     265           12 :         for(size_t i = 0; i < nsh; ++i)
     266              :         {
     267              :         //      create equidistant polynomials and its derivatives
     268            9 :                 m_vPolynom[i] = EquidistantLagrange1D(i, p);
     269           18 :                 m_vDPolynom[i] = m_vPolynom[i].derivative();
     270              :         }
     271              : 
     272              : //      reference element
     273            3 :         const ReferenceEdge& rRef = Provider<ReferenceEdge>::get();
     274              : 
     275              : //      init shape -> multi-index mapping
     276            3 :         SetLagrangeMultiIndex(m_vMultiIndex, rRef, p);
     277            3 : }
     278              : 
     279            0 : void FlexLagrangeLSFS<ReferenceEdge>::set_order(size_t order)
     280              : {
     281            0 :         LagrangeLDS<ReferenceEdge>::set_order(order);
     282              : 
     283              : //      resize
     284            0 :         p = order;
     285            0 :         nsh = p+1;
     286            0 :         m_vPolynom.resize(nsh);
     287            0 :         m_vDPolynom.resize(nsh);
     288            0 :         m_vMultiIndex.resize(nsh);
     289              : 
     290              : //      init polynomials
     291            0 :         for(size_t i = 0; i < nsh; ++i)
     292              :         {
     293              :         //      create equidistant polynomials and its derivatives
     294            0 :                 m_vPolynom[i] = EquidistantLagrange1D(i, p);
     295            0 :                 m_vDPolynom[i] = m_vPolynom[i].derivative();
     296              :         }
     297              : 
     298              : //      reference element
     299            0 :         const ReferenceEdge& rRef = Provider<ReferenceEdge>::get();
     300              : 
     301              : //      init shape -> multi-index mapping
     302            0 :         SetLagrangeMultiIndex(&m_vMultiIndex[0], rRef, p);
     303            0 : }
     304              : 
     305              : template class LagrangeLSFS<ReferenceEdge, 1>;
     306              : template class LagrangeLSFS<ReferenceEdge, 2>;
     307              : template class LagrangeLSFS<ReferenceEdge, 3>;
     308              : template class LagrangeLSFS<ReferenceEdge, 4>;
     309              : template class LagrangeLSFS<ReferenceEdge, 5>;
     310              : 
     311              : //template class FlexLagrangeLSFS<ReferenceEdge>;
     312              : 
     313              : ///////////////////////////////////////////////////////////////////////////////
     314              : // Triangle
     315              : ///////////////////////////////////////////////////////////////////////////////
     316              : 
     317              : template <int TOrder>
     318            3 : LagrangeLSFS<ReferenceTriangle, TOrder>::LagrangeLSFS()
     319           40 :         : LagrangeLDS<ReferenceTriangle>(p)
     320              : {
     321              : //      init polynomials
     322           12 :         for(size_t i = 0; i <= p; ++i)
     323              :         {
     324              :         //      create trancated equidistant polynomials and its derivatives
     325            9 :                 m_vPolynom[i] = TruncatedEquidistantLagrange1D(i, p);
     326           18 :                 m_vDPolynom[i] = m_vPolynom[i].derivative();
     327              :         }
     328              : 
     329              : //      reference element
     330            3 :         const ReferenceTriangle& rRef = Provider<ReferenceTriangle>::get();
     331              : 
     332              : //      init shape -> multi-index mapping
     333            3 :         SetLagrangeMultiIndex(m_vMultiIndex, rRef, p);
     334            3 : }
     335              : 
     336            0 : void FlexLagrangeLSFS<ReferenceTriangle>::set_order(size_t order)
     337              : {
     338            0 :         LagrangeLDS<ReferenceTriangle>::set_order(order);
     339              : 
     340              : //      resize
     341            0 :         p = order;
     342            0 :         nsh = BinomCoeff(dim+p, p);
     343              : 
     344            0 :         const size_t polSize = p+1;
     345            0 :         m_vPolynom.resize(polSize);
     346            0 :         m_vDPolynom.resize(polSize);
     347            0 :         m_vMultiIndex.resize(nsh);
     348              : 
     349              : //      init polynomials
     350            0 :         for(size_t i = 0; i <= p; ++i)
     351              :         {
     352              :         //      create trancated equidistant polynomials and its derivatives
     353            0 :                 m_vPolynom[i] = TruncatedEquidistantLagrange1D(i, p);
     354            0 :                 m_vDPolynom[i] = m_vPolynom[i].derivative();
     355              :         }
     356              : 
     357              : //      reference element
     358            0 :         const ReferenceTriangle& rRef = Provider<ReferenceTriangle>::get();
     359              : 
     360              : //      init shape -> multi-index mapping
     361            0 :         SetLagrangeMultiIndex(&m_vMultiIndex[0], rRef, p);
     362            0 : }
     363              : 
     364              : template class LagrangeLSFS<ReferenceTriangle, 1>;
     365              : template class LagrangeLSFS<ReferenceTriangle, 2>;
     366              : template class LagrangeLSFS<ReferenceTriangle, 3>;
     367              : template class LagrangeLSFS<ReferenceTriangle, 4>;
     368              : template class LagrangeLSFS<ReferenceTriangle, 5>;
     369              : 
     370              : //template class FlexLagrangeLSFS<ReferenceTriangle>;
     371              : 
     372              : ///////////////////////////////////////////////////////////////////////////////
     373              : // Quadrilateral
     374              : ///////////////////////////////////////////////////////////////////////////////
     375              : 
     376              : template <int TOrder>
     377            3 : LagrangeLSFS<ReferenceQuadrilateral, TOrder>::LagrangeLSFS()
     378           50 :         : LagrangeLDS<ReferenceQuadrilateral>(p)
     379              : {
     380              : //      init polynomials
     381           12 :         for(size_t i = 0; i <= p; ++i)
     382              :         {
     383              :         //      create truncated equidistant polynomials and its derivatives
     384            9 :                 m_vPolynom[i] = EquidistantLagrange1D(i, p);
     385           18 :                 m_vDPolynom[i] = m_vPolynom[i].derivative();
     386              :         }
     387              : 
     388              : //      reference element
     389            3 :         const ReferenceQuadrilateral& rRef = Provider<ReferenceQuadrilateral>::get();
     390              : 
     391              : //      init shape -> multi-index mapping
     392            3 :         SetLagrangeMultiIndex(m_vMultiIndex, rRef, p);
     393            3 : }
     394              : 
     395            0 : void FlexLagrangeLSFS<ReferenceQuadrilateral>::set_order(size_t order)
     396              : {
     397            0 :         LagrangeLDS<ReferenceQuadrilateral>::set_order(order);
     398              : 
     399              : //      resize
     400            0 :         p = order;
     401            0 :         nsh = (p+1)*(p+1);
     402              : 
     403              :         const size_t polSize = p+1;
     404            0 :         m_vPolynom.resize(polSize);
     405            0 :         m_vDPolynom.resize(polSize);
     406            0 :         m_vMultiIndex.resize(nsh);
     407              : 
     408              : //      init polynomials
     409            0 :         for(size_t i = 0; i <= p; ++i)
     410              :         {
     411              :         //      create truncated equidistant polynomials and its derivatives
     412            0 :                 m_vPolynom[i] = EquidistantLagrange1D(i, p);
     413            0 :                 m_vDPolynom[i] = m_vPolynom[i].derivative();
     414              :         }
     415              : 
     416              : //      reference element
     417            0 :         const ReferenceQuadrilateral& rRef = Provider<ReferenceQuadrilateral>::get();
     418              : 
     419              : //      init shape -> multi-index mapping
     420            0 :         SetLagrangeMultiIndex(&m_vMultiIndex[0], rRef, p);
     421            0 : }
     422              : 
     423              : template class LagrangeLSFS<ReferenceQuadrilateral, 1>;
     424              : template class LagrangeLSFS<ReferenceQuadrilateral, 2>;
     425              : template class LagrangeLSFS<ReferenceQuadrilateral, 3>;
     426              : template class LagrangeLSFS<ReferenceQuadrilateral, 4>;
     427              : template class LagrangeLSFS<ReferenceQuadrilateral, 5>;
     428              : 
     429              : //template class FlexLagrangeLSFS<ReferenceQuadrilateral>;
     430              : 
     431              : ///////////////////////////////////////////////////////////////////////////////
     432              : // Tetrahedron
     433              : ///////////////////////////////////////////////////////////////////////////////
     434              : 
     435              : template <int TOrder>
     436            3 : LagrangeLSFS<ReferenceTetrahedron, TOrder>::LagrangeLSFS()
     437           55 :         : LagrangeLDS<ReferenceTetrahedron>(p)
     438              : {
     439           12 :         for(size_t i = 0; i <= p; ++i)
     440              :         {
     441              :         //      create trancated equidistant polynomials and its derivatives
     442            9 :                 m_vPolynom[i] = TruncatedEquidistantLagrange1D(i, p);
     443           18 :                 m_vDPolynom[i] = m_vPolynom[i].derivative();
     444              :         }
     445              : 
     446              : //      reference element
     447            3 :         const ReferenceTetrahedron& rRef = Provider<ReferenceTetrahedron>::get();
     448              : 
     449              : //      init shape -> multi-index mapping
     450            3 :         SetLagrangeMultiIndex(m_vMultiIndex, rRef, p);
     451            3 : }
     452              : 
     453            0 : void FlexLagrangeLSFS<ReferenceTetrahedron>::set_order(size_t order)
     454              : {
     455            0 :         LagrangeLDS<ReferenceTetrahedron>::set_order(order);
     456              : 
     457              : //      resize
     458            0 :         p = order;
     459            0 :         nsh = BinomCoeff(dim + p, p);
     460              : 
     461            0 :         const size_t polSize = p+1;
     462            0 :         m_vPolynom.resize(polSize);
     463            0 :         m_vDPolynom.resize(polSize);
     464            0 :         m_vMultiIndex.resize(nsh);
     465              : 
     466              : //      init polynomials
     467            0 :         for(size_t i = 0; i <= p; ++i)
     468              :         {
     469              :         //      create trancated equidistant polynomials and its derivatives
     470            0 :                 m_vPolynom[i] = TruncatedEquidistantLagrange1D(i, p);
     471            0 :                 m_vDPolynom[i] = m_vPolynom[i].derivative();
     472              :         }
     473              : 
     474              : //      reference element
     475            0 :         const ReferenceTetrahedron& rRef = Provider<ReferenceTetrahedron>::get();
     476              : 
     477              : //      init shape -> multi-index mapping
     478            0 :         SetLagrangeMultiIndex(&m_vMultiIndex[0], rRef, p);
     479            0 : }
     480              : 
     481              : template class LagrangeLSFS<ReferenceTetrahedron, 1>;
     482              : template class LagrangeLSFS<ReferenceTetrahedron, 2>;
     483              : template class LagrangeLSFS<ReferenceTetrahedron, 3>;
     484              : template class LagrangeLSFS<ReferenceTetrahedron, 4>;
     485              : template class LagrangeLSFS<ReferenceTetrahedron, 5>;
     486              : 
     487              : //template class FlexLagrangeLSFS<ReferenceTetrahedron>;
     488              : 
     489              : ///////////////////////////////////////////////////////////////////////////////
     490              : // Prism
     491              : ///////////////////////////////////////////////////////////////////////////////
     492              : 
     493              : template <int TOrder>
     494            3 : LagrangeLSFS<ReferencePrism, TOrder>::LagrangeLSFS()
     495          103 :         : LagrangeLDS<ReferencePrism>(p)
     496              : {
     497           12 :         for(size_t i = 0; i <= p; ++i)
     498              :         {
     499              :         //      create truncated equidistant polynomials and its derivatives
     500            9 :                 m_vTruncPolynom[i] = TruncatedEquidistantLagrange1D(i, p);
     501            9 :                 m_vDTruncPolynom[i] = m_vTruncPolynom[i].derivative();
     502              : 
     503              :         //      create equidistant polynomials and its derivatives
     504            9 :                 m_vPolynom[i] = EquidistantLagrange1D(i, p);
     505           18 :                 m_vDPolynom[i] = m_vPolynom[i].derivative();
     506              :         }
     507              : 
     508              : //      reference element
     509            3 :         const ReferencePrism& rRef = Provider<ReferencePrism>::get();
     510              : 
     511              : //      init shape -> multi-index mapping
     512            3 :         SetLagrangeMultiIndex(m_vMultiIndex, rRef, p);
     513            3 : }
     514              : 
     515            0 : void FlexLagrangeLSFS<ReferencePrism>::set_order(size_t order)
     516              : {
     517            0 :         LagrangeLDS<ReferencePrism>::set_order(order);
     518              : 
     519              : //      resize
     520            0 :         p = order;
     521            0 :         dofPerLayer = BinomCoeff(2 + p, p);
     522            0 :         nsh = dofPerLayer * (p+1);
     523              : 
     524              :         const size_t polSize = p+1;
     525            0 :         m_vPolynom.resize(polSize);
     526            0 :         m_vDPolynom.resize(polSize);
     527            0 :         m_vTruncPolynom.resize(polSize);
     528            0 :         m_vDTruncPolynom.resize(polSize);
     529            0 :         m_vMultiIndex.resize(nsh);
     530              : 
     531              : //      init polynomials
     532            0 :         for(size_t i = 0; i <= p; ++i)
     533              :         {
     534              :         //      create truncated equidistant polynomials and its derivatives
     535            0 :                 m_vTruncPolynom[i] = TruncatedEquidistantLagrange1D(i, p);
     536            0 :                 m_vDTruncPolynom[i] = m_vTruncPolynom[i].derivative();
     537              : 
     538              :         //      create equidistant polynomials and its derivatives
     539            0 :                 m_vPolynom[i] = EquidistantLagrange1D(i, p);
     540            0 :                 m_vDPolynom[i] = m_vPolynom[i].derivative();
     541              :         }
     542              : 
     543              : //      reference element
     544            0 :         const ReferencePrism& rRef = Provider<ReferencePrism>::get();
     545              : 
     546              : //      init shape -> multi-index mapping
     547            0 :         SetLagrangeMultiIndex(&m_vMultiIndex[0], rRef, p);
     548            0 : }
     549              : 
     550              : template class LagrangeLSFS<ReferencePrism, 1>;
     551              : template class LagrangeLSFS<ReferencePrism, 2>;
     552              : template class LagrangeLSFS<ReferencePrism, 3>;
     553              : template class LagrangeLSFS<ReferencePrism, 4>;
     554              : template class LagrangeLSFS<ReferencePrism, 5>;
     555              : 
     556              : //template class FlexLagrangeLSFS<ReferencePrism>;
     557              : 
     558              : ///////////////////////////////////////////////////////////////////////////////
     559              : // Pyramid
     560              : ///////////////////////////////////////////////////////////////////////////////
     561              : 
     562              : template <int TOrder>
     563            1 : LagrangeLSFS<ReferencePyramid, TOrder>::LagrangeLSFS()
     564            6 :         : LagrangeLDS<ReferencePyramid>(p)
     565              : {
     566            1 :         m_vvPolynom.resize(p+1);
     567            1 :         m_vvDPolynom.resize(p+1);
     568              : 
     569            3 :         for(size_t i2 = 0; i2 <= p; ++i2)
     570              :         {
     571            2 :                 m_vvPolynom[i2].resize(p+1);
     572            2 :                 m_vvDPolynom[i2].resize(p+1);
     573              : 
     574            5 :                 for(size_t i = 0; i <= p-i2; ++i)
     575              :                 {
     576            6 :                         m_vvPolynom[i2][i] = BoundedEquidistantLagrange1D(i, p, p-i2);
     577            6 :                         m_vvDPolynom[i2][i] = m_vvPolynom[i2][i].derivative();
     578              :                 }
     579              :         }
     580              : 
     581              : //      reference element
     582              :         const ReferencePyramid& rRef =
     583            1 :                         Provider<ReferencePyramid>::get();
     584              : 
     585              : //      init shape -> multi-index mapping
     586            1 :         SetLagrangeMultiIndex(m_vMultiIndex, rRef, p);
     587            1 : }
     588              : 
     589              : template class LagrangeLSFS<ReferencePyramid, 1>;
     590              : template class LagrangeLSFS<ReferencePyramid, 2>;
     591              : 
     592              : ///////////////////////////////////////////////////////////////////////////////
     593              : // Octahedron
     594              : ///////////////////////////////////////////////////////////////////////////////
     595              : 
     596              : template <int TOrder>
     597            0 : LagrangeLSFS<ReferenceOctahedron, TOrder>::LagrangeLSFS()
     598            0 :         : LagrangeLDS<ReferenceOctahedron>(p)
     599              : {
     600              :         //UG_THROW("LagrangeLSFS<ReferenceOctahedron, TOrder>::LagrangeLSFS(): Octahedral elements currently not implemented. Use LagrangeP1 implementation instead.");
     601              : 
     602              :         if(p != 1)
     603              :                 UG_THROW("LagrangeLSFS<ReferenceOctahedron, TOrder>::LagrangeLSFS(): Octahedral elements only implemented for order p = 1.");
     604              : 
     605              : //      reference element
     606              :         const ReferenceOctahedron& rRef =
     607            0 :                         Provider<ReferenceOctahedron>::get();
     608              : 
     609              : //      init shape -> multi-index mapping
     610            0 :         SetLagrangeMultiIndex(m_vMultiIndex, rRef, p);
     611            0 : }
     612              : 
     613              : template class LagrangeLSFS<ReferenceOctahedron, 1>;
     614              : 
     615              : ///////////////////////////////////////////////////////////////////////////////
     616              : // Hexahedron
     617              : ///////////////////////////////////////////////////////////////////////////////
     618              : 
     619              : template <int TOrder>
     620            3 : LagrangeLSFS<ReferenceHexahedron, TOrder>::LagrangeLSFS()
     621          120 :         : LagrangeLDS<ReferenceHexahedron>(p)
     622              : {
     623              : //      init polynomials
     624           12 :         for(size_t i = 0; i <= p; ++i)
     625              :         {
     626              :         //      create trancated equidistant polynomials and its derivatives
     627            9 :                 m_vPolynom[i] = EquidistantLagrange1D(i, p);
     628           18 :                 m_vDPolynom[i] = m_vPolynom[i].derivative();
     629              :         }
     630              : 
     631              : //      reference element
     632            3 :         const ReferenceHexahedron& rRef = Provider<ReferenceHexahedron>::get();
     633              : 
     634              : //      init shape -> multi-index mapping
     635            3 :         SetLagrangeMultiIndex(m_vMultiIndex, rRef, p);
     636            3 : }
     637              : 
     638            0 : void FlexLagrangeLSFS<ReferenceHexahedron>::set_order(size_t order)
     639              : {
     640            0 :         LagrangeLDS<ReferenceHexahedron>::set_order(order);
     641              : 
     642              : //      resize
     643            0 :         p = order;
     644            0 :         nsh = (p+1) * (p+1) * (p+1);
     645              : 
     646              :         const size_t polSize = p+1;
     647            0 :         m_vPolynom.resize(polSize);
     648            0 :         m_vDPolynom.resize(polSize);
     649            0 :         m_vMultiIndex.resize(nsh);
     650              : 
     651              : //      init polynomials
     652            0 :         for(size_t i = 0; i <= p; ++i)
     653              :         {
     654              :         //      create trancated equidistant polynomials and its derivatives
     655            0 :                 m_vPolynom[i] = EquidistantLagrange1D(i, p);
     656            0 :                 m_vDPolynom[i] = m_vPolynom[i].derivative();
     657              :         }
     658              : 
     659              : //      reference element
     660            0 :         const ReferenceHexahedron& rRef = Provider<ReferenceHexahedron>::get();
     661              : 
     662              : //      init shape -> multi-index mapping
     663            0 :         SetLagrangeMultiIndex(&m_vMultiIndex[0], rRef, p);
     664            0 : }
     665              : 
     666              : template class LagrangeLSFS<ReferenceHexahedron, 1>;
     667              : template class LagrangeLSFS<ReferenceHexahedron, 2>;
     668              : template class LagrangeLSFS<ReferenceHexahedron, 3>;
     669              : template class LagrangeLSFS<ReferenceHexahedron, 4>;
     670              : template class LagrangeLSFS<ReferenceHexahedron, 5>;
     671              : 
     672              : } // end namespace ug
        

Generated by: LCOV version 2.0-1