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/common/geometrytype.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/q22d.hh>
00017 #include <dune/localfunctions/lagrange/prismp1.hh>
00018 #include <dune/localfunctions/lagrange/prismp2.hh>
00019 #include <dune/localfunctions/lagrange/pyramidp1.hh>
00020 
00021 namespace Dune
00022 {
00023 
00028   template<class D, class R, int d, int k>
00029   struct DimSpecificPQkLocalFiniteElementFactory
00030   {
00031     typedef typename FixedOrderLocalBasisTraits<typename P0LocalFiniteElement<D,R,d>::Traits::LocalBasisType::Traits,0>::Traits T;
00032 
00034     static LocalFiniteElementVirtualInterface<T>* create(const GeometryType& gt)
00035     {
00036       return 0;
00037     }
00038   };
00039 
00044   template<class D, class R, int k>
00045   struct DimSpecificPQkLocalFiniteElementFactory<D,R,2,k>
00046   {
00047     typedef typename FixedOrderLocalBasisTraits<typename P0LocalFiniteElement<D,R,2>::Traits::LocalBasisType::Traits,0>::Traits T;
00048     typedef Q22DLocalFiniteElement<D,R> Q22D;
00049 
00051     static LocalFiniteElementVirtualInterface<T>* create(const GeometryType& gt)
00052     {
00053       if ((gt.isCube()) and (k==2))
00054         return new LocalFiniteElementVirtualImp<Q22D>(Q22D());
00055       return 0;
00056     }
00057   };
00058 
00063   template<class D, class R, int k>
00064   struct DimSpecificPQkLocalFiniteElementFactory<D,R,3,k>
00065   {
00066     typedef typename FixedOrderLocalBasisTraits<typename P0LocalFiniteElement<D,R,3>::Traits::LocalBasisType::Traits,0>::Traits T;
00067     typedef PrismP1LocalFiniteElement<D,R> PrismP1;
00068     typedef PrismP2LocalFiniteElement<D,R> PrismP2;
00069       typedef PyramidP1LocalFiniteElement<D,R> PyramidP1;
00070 
00072     static LocalFiniteElementVirtualInterface<T>* create(const GeometryType& gt)
00073     {
00074       if ((gt.isPrism()) and (k==1))
00075         return new LocalFiniteElementVirtualImp<PrismP1>(PrismP1());
00076       if ((gt.isPrism()) and (k==2))
00077         return new LocalFiniteElementVirtualImp<PrismP2>(PrismP2());
00078       if ((gt.isPyramid()) and (k==1))
00079           return new LocalFiniteElementVirtualImp<PyramidP1>(PyramidP1());
00080       return 0;
00081     }
00082   };
00083 
00084 
00088   template<class D, class R, int dim, int k>
00089   struct PQkLocalFiniteElementFactory
00090   {
00091     typedef typename FixedOrderLocalBasisTraits<typename P0LocalFiniteElement<D,R,dim>::Traits::LocalBasisType::Traits,0>::Traits T;
00092     typedef LocalFiniteElementVirtualInterface<T> FiniteElementType;
00093     typedef P0LocalFiniteElement<D,R,dim> P0;
00094     typedef PkLocalFiniteElement<D,R,dim,k> Pk;
00095     typedef Q1LocalFiniteElement<D,R,dim> Q1;
00096 
00097 
00099     static FiniteElementType* create(const GeometryType& gt)
00100     {
00101       if (k==0)
00102         return new LocalFiniteElementVirtualImp<P0>(P0(gt));
00103 
00104       if (gt.isSimplex())
00105         return new LocalFiniteElementVirtualImp<Pk>(Pk());
00106 
00107       if ((gt.isCube()) and (k==1))
00108         return new LocalFiniteElementVirtualImp<Q1>(Q1());
00109 
00110       return DimSpecificPQkLocalFiniteElementFactory<D,R,dim,k>::create(gt);
00111     }
00112   };
00113 
00114 
00115 
00126   template<class D, class R, int dim, int k>
00127   class PQkLocalFiniteElementCache
00128   {
00129   protected:
00130     typedef typename FixedOrderLocalBasisTraits<typename P0LocalFiniteElement<D,R,dim>::Traits::LocalBasisType::Traits,0>::Traits T;
00131     typedef LocalFiniteElementVirtualInterface<T> FE;
00132     typedef typename std::map<GeometryType,FE*> FEMap;
00133 
00134   public:
00136     typedef FE FiniteElementType;
00137 
00139     PQkLocalFiniteElementCache() {}
00140 
00142     PQkLocalFiniteElementCache(const PQkLocalFiniteElementCache& other)
00143     {
00144       typename FEMap::iterator it = other.cache_.begin();
00145       typename FEMap::iterator end = other.cache_.end();
00146       for(; it!=end; ++it)
00147         cache_[it->first] = (it->second)->clone();
00148     }
00149 
00150     ~PQkLocalFiniteElementCache()
00151     {
00152       typename FEMap::iterator it = cache_.begin();
00153       typename FEMap::iterator end = cache_.end();
00154       for(; it!=end; ++it)
00155         delete it->second;
00156     }
00157 
00159     const FiniteElementType& get(const GeometryType& gt) const
00160     {
00161       typename FEMap::const_iterator it = cache_.find(gt);
00162       if (it==cache_.end())
00163       {
00164         FiniteElementType* fe = PQkLocalFiniteElementFactory<D,R,dim,k>::create(gt);
00165         if (fe==0)
00166           DUNE_THROW(Dune::NotImplemented,"No Pk/Qk like local finite element available for geometry type " << gt << " and order " << k);
00167 
00168         cache_[gt] = fe;
00169         return *fe;
00170       }
00171       return *(it->second);
00172     }
00173 
00174   protected:
00175     mutable FEMap cache_;
00176 
00177   };
00178 
00179 }
00180 
00181 #endif

Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].