dune-localfunctions
2.2.0
|
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