lobattopoints.hh

Go to the documentation of this file.
00001 #ifndef DUNE_LOBATTOBASIS_HH
00002 #define DUNE_LOBATTOBASIS_HH
00003 
00004 #include <fstream>
00005 
00006 #include <dune/common/forloop.hh>
00007 
00008 #include <dune/grid/common/topologyfactory.hh>
00009 #include <dune/grid/common/quadraturerules/lobattoquadrature.hh>
00010 #include <dune/grid/genericgeometry/referenceelements.hh>
00011 #include <dune/grid/genericgeometry/referencemappings.hh>
00012 
00013 #include <dune/localfunctions/utility/lfematrix.hh>
00014 #include <dune/localfunctions/utility/field.hh>
00015 #include <dune/localfunctions/lagrange/lagrangecoefficients.hh>
00016 #include <dune/localfunctions/lagrange/emptypoints.hh>
00017 
00018 namespace Dune
00019 {
00020 
00021   template< class Field >
00022   struct LobattoPoints
00023   {
00024     LobattoPoints ( unsigned int order )
00025     : points_( 0 )
00026     {
00027       if( order < 2 )
00028         return;
00029       points_.resize(order-1);
00030 #if HAVE_ALGLIB
00031       typedef amp::ampf< Precision< Field >::value > MPField;
00032 #else
00033       typedef Field MPField;
00034 #endif
00035       GenericGeometry::LobattoPoints<MPField> lobatto(order+1);
00036 
00037       for (unsigned int i=1;i<order;++i) {
00038         points_[i-1] = field_cast<Field>(lobatto[i].position());
00039       }
00040     }
00041 
00042     const unsigned int size() 
00043     {
00044       return points_.size();
00045     }
00046     const unsigned int order() 
00047     {
00048       return points_.size()+1;
00049     }
00050     const Field &point(int i) 
00051     {
00052       return points_[i];
00053     }
00054     std::vector<Field> points_;
00055   };
00056 
00057   template <class Field,class Topology>
00058   struct LobattoInnerPoints;
00059 
00060   template <class Field>
00061   struct LobattoInnerPoints<Field,GenericGeometry::Point>
00062   {
00063     static const unsigned int dimension = 0;
00064     static unsigned int size(const unsigned int order)
00065     {
00066       return 1;
00067     }
00068     template <unsigned int dim>
00069     static unsigned int setupSimplex(
00070                              const unsigned int iup,
00071                              const unsigned int dimStart,
00072                              unsigned int startPos,
00073                              const std::vector<Field> &points1D,
00074                              LagrangePoint< Field, dim > *points )
00075     {
00076       const unsigned int order = points1D.size()+1;
00077       unsigned int i = order+1-iup;
00078       if (i-2>=points1D.size())
00079       {
00080         return startPos;
00081       }
00082       for ( unsigned int d=0;d<dimStart;++d ) 
00083       {
00084         points[startPos].point_[d] = -points1D[i-2];
00085       }
00086         
00087       return startPos+1;
00088     }
00089     template <unsigned int dim>
00090     static void setup(const std::vector<Field> &points1D,
00091                       LagrangePoint< Field, dim > *points )
00092     {
00093       points->point_[0] = Zero<Field>();
00094     }
00095   };
00096   template <class Field,class Base>
00097   struct LobattoInnerPoints<Field,GenericGeometry::Pyramid<Base> >
00098   {
00099     typedef LobattoInnerPoints<Field,Base> LobattoBase;
00100     static const unsigned int dimension = Base::dimension+1;
00101     static unsigned int size(const unsigned int order)
00102     {
00103       if (order<=dimension) return 0;
00104       unsigned int size=0;
00105       for (unsigned int o=0;o<order-dimension;++o)
00106         size += LobattoBase::size(o+dimension);
00107       return size;
00108     }
00109     template <unsigned int dim>
00110     static unsigned int setupSimplex(
00111                              const unsigned int iup,
00112                              const unsigned int dimStart,
00113                              unsigned int startPos,
00114                              const std::vector<Field> &points1D,
00115                              LagrangePoint< Field, dim > *points )
00116     {
00117       const unsigned int order = points1D.size()+1;
00118       unsigned int endPos = startPos;
00119       for (unsigned int i=2;i<=order-iup;++i)
00120       {
00121         endPos = LobattoBase::template setupSimplex<dim>(iup+i-1,dimStart,startPos,points1D,points);
00122         for (unsigned int j=startPos;j<endPos;++j) 
00123         {
00124           for (unsigned int d=0;d<dimStart;++d) 
00125           {
00126             if ( d==dimStart-dimension )
00127               points[j].point_[d] += dimStart*points1D[i-2];
00128             else
00129               points[j].point_[d] -= points1D[i-2];
00130           }
00131         }
00132         startPos = endPos;
00133       }
00134       return endPos;
00135     }
00136     template <unsigned int dim>
00137     static void setup(const std::vector<Field> &points1D,
00138                       LagrangePoint< Field, dim > *points )
00139     {
00140       const unsigned int order = points1D.size()+1;
00141       unsigned int startPos=0,endPos=0;
00142       for (unsigned int i=2;i<=order;++i)
00143       {
00144         endPos = LobattoBase::template setupSimplex<dim>(i-1,dimension,startPos,points1D,points);
00145 
00146         for (unsigned int j=startPos;j<endPos;++j) 
00147         {
00148           for (unsigned int d=0;d<dimension;++d) 
00149           {
00150             if ( d==0 )
00151               points[j].point_[d] += 1.+int(dimension)*points1D[i-2];
00152             else
00153               points[j].point_[d] += 1.-points1D[i-2];
00154             points[j].point_[d] /= (dimension+1);
00155           }
00156         }
00157         startPos = endPos;
00158       }
00159     }
00160   };
00161   template <class Field,class Base>
00162   struct LobattoInnerPoints<Field,GenericGeometry::Prism<Base> >
00163   {
00164     typedef LobattoInnerPoints<Field,Base> LobattoBase;
00165     static const unsigned int dimension = Base::dimension+1;
00166     static unsigned int size(const unsigned int order)
00167     {
00168       return LobattoBase::size(order)*(order-1);
00169     }
00170     template <unsigned int dim>
00171     static unsigned int setupSimplex(
00172                              const unsigned int iup,
00173                              const unsigned int dimStart,
00174                              unsigned int startPos,
00175                              const std::vector<Field> &points1D,
00176                              LagrangePoint< Field, dim > *points )
00177     {
00178       const unsigned int order = points1D.size()+1;
00179       unsigned int endPos = startPos;
00180       for (unsigned int i=2;i<=order-iup;++i)
00181       {
00182         endPos = LobattoBase::template setupSimplex<dim>(iup+i-1,dimStart,startPos,points1D,points);
00183         for (unsigned int j=startPos;j<endPos;++j) 
00184         {
00185           for (unsigned int d=0;d<dimStart;++d) 
00186           {
00187             if ( d==dimStart-dimension )
00188               points[j].point_[d] += dimStart*points1D[i-2];
00189             else
00190               points[j].point_[d] -= points1D[i-2];
00191           }
00192         }
00193         startPos = endPos;
00194       }
00195       return endPos;
00196     }
00197     template <unsigned int dim>
00198     static void setup(const std::vector<Field> &points1D,
00199                       LagrangePoint< Field, dim > *points )
00200     {
00201       const unsigned int order = points1D.size()+1;
00202       assert(dim>=dimension);
00203       assert(points1D.size()==order-1);
00204       LobattoBase::template setup<dim>(points1D,points);
00205       const unsigned int baseSize = LobattoBase::size(order);
00206       for (unsigned int q=0;q<points1D.size();q++)
00207       {
00208         for (unsigned int i=0;i<baseSize;++i)
00209         {
00210           const unsigned int pos = q*baseSize+i;
00211           for (unsigned int d=0;d<dimension-1;++d)
00212             points[pos].point_[d] = points[i].point_[d];
00213           points[pos].point_[dimension-1]=points1D[q];
00214         }
00215       }
00216     }
00217   };
00218 
00219   template< class F, unsigned int dim >
00220   struct LobattoPointSet : public EmptyPointSet<F,dim>
00221   {
00222     // friend class LagrangeCoefficientsFactory<LobattoPointSet,dim,F>;
00223     static const unsigned int dimension = dim; 
00224     typedef F Field;
00225     typedef EmptyPointSet<F,dim> Base;
00226     typedef typename Base::LagrangePoint Point;
00227     LobattoPointSet(unsigned int order)
00228       : Base(order)
00229     {
00230     }
00231 
00232     template< class Topology >
00233     bool build ( )
00234     {
00235       unsigned int order = Base::order();
00236       LobattoPoints<Field> points1D(order);
00237       ForLoop<Setup<Topology>::template InitCodim,0,dimension>::
00238         apply(order,points1D.points_,points_);
00239       return true;
00240     }
00241     template< class Topology >
00242     static bool supports ( unsigned int order )
00243     {
00244       if ( GenericGeometry::IsSimplex< Topology >::value ||
00245            GenericGeometry::IsGeneralizedPrism< Topology >::value )
00246         return true;
00247       else
00248         return false;
00249     }
00250     protected:
00251     using Base::points_;
00252     private:
00253     template <class Topology>
00254     struct Setup 
00255     {
00256       template <int pdim>
00257       struct InitCodim 
00258       {
00259         static const unsigned int codim = dimension-pdim;
00260         static void apply(const unsigned int order, 
00261                           const std::vector<Field> &points1D,
00262                           std::vector<Point> &points) 
00263         {
00264           const unsigned int size = GenericGeometry::Size<Topology,codim>::value;
00265           ForLoop<InitSub,0,size-1>::apply(order,points1D,points);
00266         }
00267         template <int i>
00268         struct InitSub
00269         {
00270           typedef typename GenericGeometry::SubTopology<Topology,codim,i>::type SubTopology;
00271           static void apply(const unsigned int order,
00272                             const std::vector<Field> &points1D,
00273                             std::vector<Point> &points)
00274           {
00275             Setup<Topology>::template Init<SubTopology>::template apply<i>(order,points1D,points);
00276           }
00277         };
00278       };
00279       template <class SubTopology>
00280       struct Init
00281       {
00282         static const unsigned int codimension = dimension - SubTopology::dimension;
00283         typedef GenericGeometry::ReferenceMappings< Field, dimension > RefMappings;
00284         typedef typename RefMappings::Container RefMappingsContainer;
00285         typedef typename RefMappingsContainer::template Codim< codimension >::Mapping Mapping;
00286         typedef LobattoInnerPoints<Field,SubTopology> InnerPoints;
00287         template <unsigned int subEntity>
00288         static void apply(const unsigned int order, 
00289                           const std::vector<Field> &points1D,
00290                           std::vector<Point> &points) 
00291         {
00292           unsigned int oldSize = points.size();
00293           unsigned int size = InnerPoints::size(order);
00294           if (size==0)
00295             return;
00296           points.resize(oldSize+size);
00297           std::vector< LagrangePoint<Field,dimension-codimension> > subPoints(size);
00298           
00299           InnerPoints::template setup<dimension-codimension>( points1D,&(subPoints[0]) );
00300 
00301           const RefMappingsContainer &refMappings = RefMappings::container( Topology::id );
00302           const Mapping &mapping = refMappings.template mapping< codimension >( subEntity );
00303 
00304           LagrangePoint<Field,dimension> *p = &(points[oldSize]);
00305           for ( unsigned int nr = 0; nr<size; ++nr, ++p)
00306           {
00307             p->point_ = mapping.global( subPoints[nr].point_ );
00308             p->localKey_ = LocalKey( subEntity, codimension, nr );
00309             #ifndef NDEBUG
00310             bool test = GenericGeometry::ReferenceElement<Topology,Field>::checkInside(p->point_);
00311             if (!test)
00312               std::cout << "not inside" << std::endl;
00313             #endif
00314           }
00315         }
00316       };
00317     };
00318 
00319   };
00320 }
00321 #endif // DUNE_LOBATTOBASIS_HH
00322 
Generated on Sat Apr 24 11:15:34 2010 for dune-localfunctions by  doxygen 1.6.3