dune-localfunctions  2.2.0
virtualinterface.hh
Go to the documentation of this file.
00001 // -*- tab-width: 8; indent-tabs-mode: nil -*-
00002 // vi: set ts=8 sw=2 et sts=2:
00003 #ifndef DUNE_VIRTUALINTERFACE_HH
00004 #define DUNE_VIRTUALINTERFACE_HH
00005 
00006 #include<dune/common/function.hh>
00007 
00008 #include<dune/geometry/type.hh>
00009 
00010 #include<dune/localfunctions/common/localbasis.hh>
00011 #include<dune/localfunctions/common/localkey.hh>
00012 #include<dune/localfunctions/common/localfiniteelementtraits.hh>
00013 
00014 namespace Dune
00015 {
00016 
00017   // forward declaration needed by the helper traits
00018   template<class DomainType, class RangeType>
00019   class LocalInterpolationVirtualInterface;
00020 
00021   template<class T>
00022   class LocalBasisVirtualInterface;
00023 
00024   // -----------------------------------------------------------------
00025   // Helper traits classes
00026   // -----------------------------------------------------------------
00027 
00033   template<class T>
00034   struct LowerOrderLocalBasisTraits
00035   {
00037     typedef LocalBasisTraits<
00038         typename T::DomainFieldType,
00039         T::dimDomain,
00040         typename T::DomainType,
00041         typename T::RangeFieldType,
00042         T::dimRange,
00043         typename T::RangeType,
00044         typename T::JacobianType,
00045         T::diffOrder-1> Traits;
00046   };
00047 
00054   template<class T, int order>
00055   struct FixedOrderLocalBasisTraits
00056   {
00058     typedef LocalBasisTraits<
00059         typename T::DomainFieldType,
00060         T::dimDomain,
00061         typename T::DomainType,
00062         typename T::RangeFieldType,
00063         T::dimRange,
00064         typename T::RangeType,
00065         typename T::JacobianType,
00066         order> Traits;
00067   };
00068 
00074   template<class FE>
00075   class LocalFiniteElementFunctionBase
00076   {
00077     typedef typename FE::Traits::LocalBasisType::Traits::DomainType DomainType;
00078     typedef typename FE::Traits::LocalBasisType::Traits::RangeType RangeType;
00079 
00080     typedef LocalInterpolationVirtualInterface<DomainType, RangeType> Interface;
00081     typedef typename FE::Traits::LocalInterpolationType Implementation;
00082 
00083   public:
00084 
00085     typedef VirtualFunction<DomainType, RangeType> VirtualFunctionBase;
00086     typedef Function<const DomainType&, RangeType&> FunctionBase;
00087 
00093     typedef typename SelectType<IsBaseOf<Interface, Implementation>::value, VirtualFunctionBase, FunctionBase>::Type type;
00094   };
00095 
00096 
00097 
00098   // -----------------------------------------------------------------
00099   // Basis
00100   // -----------------------------------------------------------------
00101 
00102 // current versions of doxygen (<= 1.6.2) enter an infinite loop when parsing
00103 // the following class
00104 #ifndef DOXYGEN
00105 
00119   template<class T>
00120   class LocalBasisVirtualInterfaceBase :
00121     public virtual LocalBasisVirtualInterface<typename LowerOrderLocalBasisTraits<T>::Traits>
00122   {
00123     typedef LocalBasisVirtualInterface<typename LowerOrderLocalBasisTraits<T>::Traits> BaseInterface;
00124   public:
00125     typedef T Traits;
00126 
00128     virtual void evaluate (
00129         const typename Dune::template array<int,Traits::diffOrder>& directions,
00130         const typename Traits::DomainType& in,
00131         std::vector<typename Traits::RangeType>& out) const = 0;
00132 
00133     using BaseInterface::evaluate;
00134   };
00135 #endif // DOXYGEN
00136 
00143   template<class DF, int n, class D, class RF, int m, class R, class J>
00144   class LocalBasisVirtualInterfaceBase<LocalBasisTraits<DF,n,D,RF,m,R,J,0> >
00145   {
00146   public:
00147     typedef LocalBasisTraits<DF,n,D,RF,m,R,J,0> Traits;
00148 
00149     virtual ~LocalBasisVirtualInterfaceBase() {}
00150 
00152     virtual unsigned int size () const = 0;
00153 
00155     virtual unsigned int order () const = 0;
00156 
00162     virtual void evaluateFunction (const typename Traits::DomainType& in,
00163         std::vector<typename Traits::RangeType>& out) const = 0;
00164 
00173     virtual void evaluateJacobian(const typename Traits::DomainType& in,         // position
00174                                   std::vector<typename Traits::JacobianType>& out) const = 0;
00175 
00177     virtual void evaluate (
00178         const typename Dune::template array<int,Traits::diffOrder>& directions,
00179         const typename Traits::DomainType& in,
00180         std::vector<typename Traits::RangeType>& out) const = 0;
00181 
00182   };
00183 
00193   template<class T>
00194   class LocalBasisVirtualInterface :
00195     public virtual LocalBasisVirtualInterfaceBase<T>
00196   {
00197     typedef LocalBasisVirtualInterfaceBase<T> BaseInterface;
00198   public:
00199     typedef T Traits;
00200 
00202     template <int k>
00203     void evaluate (
00204         const typename Dune::template array<int,k>& directions,
00205         const typename Traits::DomainType& in,
00206         std::vector<typename Traits::RangeType>& out) const
00207     {
00208       typedef LocalBasisVirtualInterfaceBase<typename FixedOrderLocalBasisTraits<T,k>::Traits > OrderKBaseInterface;
00209       const OrderKBaseInterface& asBase = *this;
00210       asBase.evaluate(directions, in, out);
00211     }
00212 
00213     using BaseInterface::size;
00214     using BaseInterface::order;
00215     using BaseInterface::evaluateFunction;
00216     using BaseInterface::evaluateJacobian;
00217     /* Unfortunately, the intel compiler cannot use the different evaluate
00218      * methods with varying argument lists. :-( */
00219 #ifndef __INTEL_COMPILER
00220     using BaseInterface::evaluate;
00221 #endif
00222   };
00223 
00224 
00225 
00226 
00227   // -----------------------------------------------------------------
00228   // Interpolation
00229   // -----------------------------------------------------------------
00230 
00243   template<class DomainType, class RangeType>
00244   class LocalInterpolationVirtualInterfaceBase
00245   {
00246   public:
00247 
00249     typedef Dune::VirtualFunction<DomainType, RangeType> FunctionType;
00250 
00252     typedef typename RangeType::field_type CoefficientType;
00253 
00254     virtual ~LocalInterpolationVirtualInterfaceBase() {}
00255 
00263     virtual void interpolate (const FunctionType& f, std::vector<CoefficientType>& out) const = 0;
00264   };
00265 
00273   template<class DomainType, class RangeType>
00274   class LocalInterpolationVirtualInterface
00275     : public LocalInterpolationVirtualInterfaceBase<DomainType, RangeType>
00276   {
00277   public:
00278 
00280     typedef Dune::VirtualFunction<DomainType, RangeType> FunctionType;
00281 
00283     typedef typename RangeType::field_type CoefficientType;
00284 
00285 
00286     virtual ~LocalInterpolationVirtualInterface() {}
00287 
00288     // This method is only notet again for to make the documentation complete.
00289 
00297     virtual void interpolate (const FunctionType& f, std::vector<CoefficientType>& out) const = 0;
00298 
00301     template<class F>
00302     void interpolate (const F& f, std::vector<CoefficientType>& out) const
00303     {
00304       const LocalInterpolationVirtualInterfaceBase<DomainType, RangeType>& asBase = *this;
00305       asBase.interpolate(VirtualFunctionWrapper<F>(f),out);
00306     }
00307 
00308     template<class F, class C>
00309     void interpolate (const F& f, std::vector<C>& out) const
00310     {
00311       std::vector<CoefficientType> outDummy;
00312       const LocalInterpolationVirtualInterfaceBase<DomainType, RangeType>& asBase = *this;
00313       asBase.interpolate(VirtualFunctionWrapper<F>(f),outDummy);
00314       out.resize(outDummy.size());
00315       for(typename std::vector<CoefficientType>::size_type i=0; i<outDummy.size(); ++i)
00316         out[i] = outDummy[i];
00317     }
00318 
00319   private:
00320 
00321     template <typename F>
00322     struct VirtualFunctionWrapper
00323       : public FunctionType
00324     {
00325     public:
00326       VirtualFunctionWrapper(const F &f)
00327         : f_(f)
00328       {}
00329 
00330       virtual ~VirtualFunctionWrapper() {}
00331 
00332       virtual void evaluate(const DomainType& x, RangeType& y) const
00333       {
00334         f_.evaluate(x,y);
00335       }
00336 
00337       const F &f_;
00338     };
00339   };
00340 
00341 
00342 
00343   // -----------------------------------------------------------------
00344   // Coefficients
00345   // -----------------------------------------------------------------
00346 
00352   class LocalCoefficientsVirtualInterface
00353   {
00354   public:
00355 
00356     virtual ~LocalCoefficientsVirtualInterface() {}
00357 
00359     virtual std::size_t size () const = 0;
00360 
00362     const virtual LocalKey& localKey (std::size_t i) const = 0;
00363 
00364   };
00365 
00366 
00367 
00368   // -----------------------------------------------------------------
00369   // Finite Element
00370   // -----------------------------------------------------------------
00371 
00378   template<class T>
00379   class LocalFiniteElementVirtualInterface
00380     : public virtual LocalFiniteElementVirtualInterface<typename LowerOrderLocalBasisTraits<T>::Traits >
00381   {
00382     typedef LocalFiniteElementVirtualInterface<typename LowerOrderLocalBasisTraits<T>::Traits > BaseInterface;
00383 
00384   public:
00385     typedef LocalFiniteElementTraits<
00386       LocalBasisVirtualInterface<T>,
00387       LocalCoefficientsVirtualInterface,
00388       LocalInterpolationVirtualInterface<
00389         typename T::DomainType,
00390         typename T::RangeType> > Traits;
00391 
00393     virtual const typename Traits::LocalBasisType& localBasis () const = 0;
00394 
00395     using BaseInterface::localBasis;
00396     using BaseInterface::localCoefficients;
00397     using BaseInterface::localInterpolation;
00398     using BaseInterface::type;
00399 
00400     virtual LocalFiniteElementVirtualInterface<T>* clone() const = 0;
00401   };
00402 
00403 
00410   template<class DF, int n, class D, class RF, int m, class R, class J>
00411   class LocalFiniteElementVirtualInterface<LocalBasisTraits<DF,n,D,RF,m,R,J,0> >
00412   {
00413     typedef LocalBasisTraits<DF,n,D,RF,m,R,J,0> T;
00414 
00415   public:
00416     typedef LocalFiniteElementTraits<
00417       LocalBasisVirtualInterface<T>,
00418       LocalCoefficientsVirtualInterface,
00419       LocalInterpolationVirtualInterface<
00420         typename T::DomainType,
00421         typename T::RangeType> > Traits;
00422 
00423     virtual ~LocalFiniteElementVirtualInterface() {}
00424 
00426     virtual const typename Traits::LocalBasisType& localBasis () const = 0;
00427 
00429     virtual const typename Traits::LocalCoefficientsType& localCoefficients () const = 0;
00430 
00432     virtual const typename Traits::LocalInterpolationType& localInterpolation () const = 0;
00433 
00435     virtual const GeometryType type () const = 0;
00436 
00437     virtual LocalFiniteElementVirtualInterface<T>* clone() const = 0;
00438   };
00439 
00440 }
00441 #endif