dune-localfunctions  2.2.0
pqkfactory.hh
Go to the documentation of this file.
00001 // -*- tab-width: 4; indent-tabs-mode: nil -*-
00002 // vi: set ts=4 sw=2 et sts=2:
00003 #ifndef DUNE_PQK_FACTORY_HH
00004 #define DUNE_PQK_FACTORY_HH
00005 
00006 #include <map>
00007 
00008 #include <dune/geometry/type.hh>
00009 
00010 #include <dune/localfunctions/common/virtualinterface.hh>
00011 #include <dune/localfunctions/common/virtualwrappers.hh>
00012 
00013 #include <dune/localfunctions/lagrange/p0.hh>
00014 #include <dune/localfunctions/lagrange/pk.hh>
00015 #include <dune/localfunctions/lagrange/q1.hh>
00016 #include <dune/localfunctions/lagrange/q2.hh>
00017 #include <dune/localfunctions/lagrange/prismp1.hh>
00018 #include <dune/localfunctions/lagrange/prismp2.hh>
00019 #include <dune/localfunctions/lagrange/pyramidp1.hh>
00020 #include <dune/localfunctions/lagrange/pyramidp2.hh>
00021 
00022 namespace Dune
00023 {
00024 
00029   template<class D, class R, int d, int k>
00030   struct DimSpecificPQkLocalFiniteElementFactory
00031   {
00032     typedef typename FixedOrderLocalBasisTraits<typename P0LocalFiniteElement<D,R,d>::Traits::LocalBasisType::Traits,0>::Traits T;
00033 
00035     static LocalFiniteElementVirtualInterface<T>* create(const GeometryType& gt)
00036     {
00037       return 0;
00038     }
00039   };
00040 
00045   template<class D, class R, int k>
00046   struct DimSpecificPQkLocalFiniteElementFactory<D,R,2,k>
00047   {
00048     typedef typename FixedOrderLocalBasisTraits<typename P0LocalFiniteElement<D,R,2>::Traits::LocalBasisType::Traits,0>::Traits T;
00049     typedef Q2LocalFiniteElement<D,R,2> Q22D;
00050 
00052     static LocalFiniteElementVirtualInterface<T>* create(const GeometryType& gt)
00053     {
00054       if ((gt.isCube()) and (k==2))
00055         return new LocalFiniteElementVirtualImp<Q22D>(Q22D());
00056       return 0;
00057     }
00058   };
00059 
00064   template<class D, class R, int k>
00065   struct DimSpecificPQkLocalFiniteElementFactory<D,R,3,k>
00066   {
00067     typedef typename FixedOrderLocalBasisTraits<typename P0LocalFiniteElement<D,R,3>::Traits::LocalBasisType::Traits,0>::Traits T;
00068     typedef PrismP1LocalFiniteElement<D,R> PrismP1;
00069     typedef PrismP2LocalFiniteElement<D,R> PrismP2;
00070       typedef PyramidP1LocalFiniteElement<D,R> PyramidP1;
00071       typedef PyramidP2LocalFiniteElement<D,R> PyramidP2;
00072 
00074     static LocalFiniteElementVirtualInterface<T>* create(const GeometryType& gt)
00075     {
00076       if ((gt.isPrism()) and (k==1))
00077         return new LocalFiniteElementVirtualImp<PrismP1>(PrismP1());
00078       if ((gt.isPrism()) and (k==2))
00079         return new LocalFiniteElementVirtualImp<PrismP2>(PrismP2());
00080       if ((gt.isPyramid()) and (k==1))
00081           return new LocalFiniteElementVirtualImp<PyramidP1>(PyramidP1());
00082       if ((gt.isPyramid()) and (k==2))
00083           return new LocalFiniteElementVirtualImp<PyramidP2>(PyramidP2());
00084       return 0;
00085     }
00086   };
00087 
00088 
00092   template<class D, class R, int dim, int k>
00093   struct PQkLocalFiniteElementFactory
00094   {
00095     typedef typename FixedOrderLocalBasisTraits<typename P0LocalFiniteElement<D,R,dim>::Traits::LocalBasisType::Traits,0>::Traits T;
00096     typedef LocalFiniteElementVirtualInterface<T> FiniteElementType;
00097     typedef P0LocalFiniteElement<D,R,dim> P0;
00098     typedef PkLocalFiniteElement<D,R,dim,k> Pk;
00099     typedef Q1LocalFiniteElement<D,R,dim> Q1;
00100 
00101 
00103     static FiniteElementType* create(const GeometryType& gt)
00104     {
00105       if (k==0)
00106         return new LocalFiniteElementVirtualImp<P0>(P0(gt));
00107 
00108       if (gt.isSimplex())
00109         return new LocalFiniteElementVirtualImp<Pk>(Pk());
00110 
00111       if ((gt.isCube()) and (k==1))
00112         return new LocalFiniteElementVirtualImp<Q1>(Q1());
00113 
00114       return DimSpecificPQkLocalFiniteElementFactory<D,R,dim,k>::create(gt);
00115     }
00116   };
00117 
00118 
00119 
00130   template<class D, class R, int dim, int k>
00131   class PQkLocalFiniteElementCache
00132   {
00133   protected:
00134     typedef typename FixedOrderLocalBasisTraits<typename P0LocalFiniteElement<D,R,dim>::Traits::LocalBasisType::Traits,0>::Traits T;
00135     typedef LocalFiniteElementVirtualInterface<T> FE;
00136     typedef typename std::map<GeometryType,FE*> FEMap;
00137 
00138   public:
00140     typedef FE FiniteElementType;
00141 
00143     PQkLocalFiniteElementCache() {}
00144 
00146     PQkLocalFiniteElementCache(const PQkLocalFiniteElementCache& other)
00147     {
00148       typename FEMap::iterator it = other.cache_.begin();
00149       typename FEMap::iterator end = other.cache_.end();
00150       for(; it!=end; ++it)
00151         cache_[it->first] = (it->second)->clone();
00152     }
00153 
00154     ~PQkLocalFiniteElementCache()
00155     {
00156       typename FEMap::iterator it = cache_.begin();
00157       typename FEMap::iterator end = cache_.end();
00158       for(; it!=end; ++it)
00159         delete it->second;
00160     }
00161 
00163     const FiniteElementType& get(const GeometryType& gt) const
00164     {
00165       typename FEMap::const_iterator it = cache_.find(gt);
00166       if (it==cache_.end())
00167       {
00168         FiniteElementType* fe = PQkLocalFiniteElementFactory<D,R,dim,k>::create(gt);
00169         if (fe==0)
00170           DUNE_THROW(Dune::NotImplemented,"No Pk/Qk like local finite element available for geometry type " << gt << " and order " << k);
00171 
00172         cache_[gt] = fe;
00173         return *fe;
00174       }
00175       return *(it->second);
00176     }
00177 
00178   protected:
00179     mutable FEMap cache_;
00180 
00181   };
00182 
00183 }
00184 
00185 #endif