dune-localfunctions
2.2.0
|
00001 // -*- tab-width: 8; indent-tabs-mode: nil -*- 00002 // vi: set ts=8 sw=2 et sts=2: 00003 #ifndef DUNE_VIRTUALWRAPPERS_HH 00004 #define DUNE_VIRTUALWRAPPERS_HH 00005 00006 #include<dune/common/function.hh> 00007 00008 #include<dune/localfunctions/common/localbasis.hh> 00009 #include<dune/localfunctions/common/localkey.hh> 00010 #include<dune/localfunctions/common/virtualinterface.hh> 00011 00012 namespace Dune 00013 { 00014 00015 // forward declaration needed by friend declarations 00016 template<class Imp> 00017 class LocalFiniteElementVirtualImp; 00018 00019 // default clone method is the copy constructor 00020 template<class Imp, bool IsInterface> 00021 struct LocalFiniteElementCloneFactoryHelper 00022 { 00023 static Imp* clone(const Imp& imp) 00024 { 00025 return new Imp(imp); 00026 } 00027 }; 00028 00029 // if FE derives from virtual interface the clone method is used 00030 template<class Imp> 00031 struct LocalFiniteElementCloneFactoryHelper<Imp, true> 00032 { 00033 static Imp* clone(const Imp& imp) 00034 { 00035 return imp.clone(); 00036 } 00037 }; 00038 00039 // factory template to clone and create an objects 00040 template<class Imp> 00041 struct LocalFiniteElementCloneFactory 00042 { 00043 typedef LocalFiniteElementVirtualInterface<typename Imp::Traits::LocalBasisType::Traits> Interface; 00044 00045 static Imp* clone(const Imp& imp) 00046 { 00047 return LocalFiniteElementCloneFactoryHelper<Imp, IsBaseOf<Interface, Imp>::value>::clone(imp); 00048 } 00049 00050 static Imp* create() 00051 { 00052 return new Imp; 00053 } 00054 }; 00055 00056 00057 00058 // ----------------------------------------------------------------- 00059 // Basis 00060 // ----------------------------------------------------------------- 00061 00071 template<class T , class Imp> 00072 class LocalBasisVirtualImp 00073 : public virtual LocalBasisVirtualInterface<T>, 00074 public LocalBasisVirtualImp<typename LowerOrderLocalBasisTraits<T>::Traits,Imp> 00075 { 00076 template<class FEImp> 00077 friend class LocalFiniteElementVirtualImp; 00078 00079 typedef LocalBasisVirtualImp<typename LowerOrderLocalBasisTraits<T>::Traits,Imp> Base; 00080 00081 protected: 00082 00084 LocalBasisVirtualImp( const Imp &imp ) 00085 : Base(imp) 00086 {} 00087 00088 public: 00089 typedef T Traits; 00090 00091 using Base::size; 00092 using Base::order; 00093 using Base::evaluateFunction; 00094 using Base::evaluateJacobian; 00095 using Base::evaluate; 00096 00098 inline void evaluate( 00099 const typename Dune::template array<int,Traits::diffOrder>& directions, 00100 const typename Traits::DomainType& in, 00101 std::vector<typename Traits::RangeType>& out) const 00102 { 00103 // Even for double virtualization it is save to call the template method 00104 // since the interface provides it redirecting to the virtual method 00105 // of the derived class 00106 // 00107 // Unfortunately not all compiler can determine Traits::diffOrder from the 00108 // type of the arument directions 00109 impl_.template evaluate<Traits::diffOrder>(directions, in, out); 00110 } 00111 00112 protected: 00113 using Base::impl_; 00114 00115 }; 00116 00117 00125 template<class DF, int n, class D, class RF, int m, class R, class J, class Imp> 00126 class LocalBasisVirtualImp<LocalBasisTraits<DF,n,D,RF,m,R,J,0>, Imp> 00127 : public virtual LocalBasisVirtualInterface<LocalBasisTraits<DF,n,D,RF,m,R,J,0> > 00128 { 00129 template<class FEImp> 00130 friend class LocalFiniteElementVirtualImp; 00131 00132 protected: 00133 00135 LocalBasisVirtualImp( const Imp &imp ) 00136 : impl_(imp) 00137 {} 00138 00139 public: 00140 typedef LocalBasisTraits<DF,n,D,RF,m,R,J,0> Traits; 00141 00143 unsigned int size () const 00144 { 00145 return impl_.size(); 00146 } 00147 00149 unsigned int order () const 00150 { 00151 return impl_.order(); 00152 } 00153 00155 inline void evaluateFunction (const typename Traits::DomainType& in, 00156 std::vector<typename Traits::RangeType>& out) const 00157 { 00158 impl_.evaluateFunction(in,out); 00159 } 00160 00162 inline void evaluateJacobian( 00163 const typename Traits::DomainType& in, 00164 std::vector<typename Traits::JacobianType>& out) const 00165 { 00166 impl_.evaluateJacobian(in,out); 00167 } 00168 00170 inline void evaluate( 00171 const typename Dune::template array<int,Traits::diffOrder>& directions, 00172 const typename Traits::DomainType& in, 00173 std::vector<typename Traits::RangeType>& out) const 00174 { 00175 // impl_.template evaluate<Traits::diffOrder> (directions, in,out); 00176 // impl_.template evaluate<0> (directions, in,out); 00177 impl_.evaluateFunction(in,out); 00178 } 00179 00180 protected: 00181 const Imp& impl_; 00182 }; 00183 00184 00185 00186 // ----------------------------------------------------------------- 00187 // Interpolation 00188 // ----------------------------------------------------------------- 00189 00198 template<class DomainType, class RangeType, class Imp> 00199 class LocalInterpolationVirtualImp 00200 : public LocalInterpolationVirtualInterface< DomainType, RangeType > 00201 { 00202 template<class FEImp> 00203 friend class LocalFiniteElementVirtualImp; 00204 00205 typedef LocalInterpolationVirtualInterface< DomainType, RangeType > Base; 00206 00207 protected: 00208 00210 LocalInterpolationVirtualImp( const Imp &imp) 00211 : impl_(imp) {} 00212 00213 public: 00214 00215 typedef typename Base::FunctionType FunctionType; 00216 00217 typedef typename Base::CoefficientType CoefficientType; 00218 00220 virtual void interpolate (const FunctionType& f, std::vector<CoefficientType>& out) const 00221 { 00222 impl_.interpolate(f,out); 00223 } 00224 00225 protected: 00226 const Imp& impl_; 00227 00228 }; 00229 00230 00231 00232 // ----------------------------------------------------------------- 00233 // Coefficients 00234 // ----------------------------------------------------------------- 00235 00242 template<class Imp> 00243 class LocalCoefficientsVirtualImp 00244 : public LocalCoefficientsVirtualInterface 00245 { 00246 template<class FEImp> 00247 friend class LocalFiniteElementVirtualImp; 00248 00249 protected: 00250 00252 LocalCoefficientsVirtualImp( const Imp &imp ) 00253 : impl_(imp) 00254 {} 00255 00256 public: 00257 00259 std::size_t size () const 00260 { 00261 return impl_.size(); 00262 } 00263 00265 const LocalKey& localKey (std::size_t i) const 00266 { 00267 return impl_.localKey(i); 00268 } 00269 00270 protected: 00271 const Imp& impl_; 00272 00273 }; 00274 00275 00276 00277 // ----------------------------------------------------------------- 00278 // Finite Element 00279 // ----------------------------------------------------------------- 00280 00289 template<class Imp> 00290 class LocalFiniteElementVirtualImp 00291 : public virtual LocalFiniteElementVirtualInterface<typename Imp::Traits::LocalBasisType::Traits> 00292 { 00293 typedef typename Imp::Traits::LocalBasisType::Traits T; 00294 typedef LocalFiniteElementVirtualInterface<T> Interface; 00295 00296 public: 00297 typedef typename Interface::Traits Traits; 00298 00300 LocalFiniteElementVirtualImp( const Imp &imp ) 00301 : impl_(LocalFiniteElementCloneFactory<Imp>::clone(imp)), 00302 localBasisImp_(impl_->localBasis()), 00303 localCoefficientsImp_(impl_->localCoefficients()), 00304 localInterpolationImp_(impl_->localInterpolation()) 00305 {} 00306 00308 LocalFiniteElementVirtualImp() 00309 : impl_(LocalFiniteElementCloneFactory<Imp>::create()), 00310 localBasisImp_(impl_->localBasis()), 00311 localCoefficientsImp_(impl_->localCoefficients()), 00312 localInterpolationImp_(impl_->localInterpolation()) 00313 {} 00314 00316 LocalFiniteElementVirtualImp(const LocalFiniteElementVirtualImp& other) 00317 : impl_(LocalFiniteElementCloneFactory<Imp>::clone(*other.impl_)), 00318 localBasisImp_(impl_->localBasis()), 00319 localCoefficientsImp_(impl_->localCoefficients()), 00320 localInterpolationImp_(impl_->localInterpolation()) 00321 {} 00322 00323 ~LocalFiniteElementVirtualImp() 00324 { 00325 delete impl_; 00326 } 00327 00329 const typename Traits::LocalBasisType& localBasis () const 00330 { 00331 return localBasisImp_; 00332 } 00333 00335 const typename Traits::LocalCoefficientsType& localCoefficients () const 00336 { 00337 return localCoefficientsImp_; 00338 } 00339 00341 const typename Traits::LocalInterpolationType& localInterpolation () const 00342 { 00343 return localInterpolationImp_; 00344 } 00345 00347 const GeometryType type () const 00348 { 00349 return impl_->type(); 00350 } 00351 00357 virtual LocalFiniteElementVirtualImp<Imp>* clone() const 00358 { 00359 return new LocalFiniteElementVirtualImp<Imp>(*this); 00360 } 00361 00362 protected: 00363 const Imp* impl_; 00364 00366 const LocalBasisVirtualImp<T, typename Imp::Traits::LocalBasisType> localBasisImp_; 00367 const LocalCoefficientsVirtualImp<typename Imp::Traits::LocalCoefficientsType> localCoefficientsImp_; 00368 const LocalInterpolationVirtualImp<typename T::DomainType, 00369 typename T::RangeType, 00370 typename Imp::Traits::LocalInterpolationType> localInterpolationImp_; 00371 }; 00372 } 00373 #endif