dune-localfunctions  2.1.1
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/geometrytype.hh>
00007 #include<dune/common/function.hh>
00008 
00009 #include<dune/localfunctions/common/localbasis.hh>
00010 #include<dune/localfunctions/common/localkey.hh>
00011 #include<dune/localfunctions/common/localfiniteelementtraits.hh>
00012 
00013 namespace Dune
00014 {
00015 
00016   // forward declaration needed by the helper traits
00017   template<class DomainType, class RangeType>
00018   class LocalInterpolationVirtualInterface;
00019 
00020   template<class T>
00021   class LocalBasisVirtualInterface;
00022 
00023   // -----------------------------------------------------------------
00024   // Helper traits classes
00025   // -----------------------------------------------------------------
00026 
00032   template<class T>
00033   struct LowerOrderLocalBasisTraits
00034   {
00036     typedef LocalBasisTraits<
00037         typename T::DomainFieldType,
00038         T::dimDomain,
00039         typename T::DomainType,
00040         typename T::RangeFieldType,
00041         T::dimRange,
00042         typename T::RangeType,
00043         typename T::JacobianType,
00044         T::diffOrder-1> Traits;
00045   };
00046 
00053   template<class T, int order>
00054   struct FixedOrderLocalBasisTraits
00055   {
00057     typedef LocalBasisTraits<
00058         typename T::DomainFieldType,
00059         T::dimDomain,
00060         typename T::DomainType,
00061         typename T::RangeFieldType,
00062         T::dimRange,
00063         typename T::RangeType,
00064         typename T::JacobianType,
00065         order> Traits;
00066   };
00067 
00073   template<class FE>
00074   class LocalFiniteElementFunctionBase
00075   {
00076     typedef typename FE::Traits::LocalBasisType::Traits::DomainType DomainType;
00077     typedef typename FE::Traits::LocalBasisType::Traits::RangeType RangeType;
00078 
00079     typedef LocalInterpolationVirtualInterface<DomainType, RangeType> Interface;
00080     typedef typename FE::Traits::LocalInterpolationType Implementation;
00081 
00082   public:
00083 
00084     typedef VirtualFunction<DomainType, RangeType> VirtualFunctionBase;
00085     typedef Function<const DomainType&, RangeType&> FunctionBase;
00086 
00092     typedef typename SelectType<IsBaseOf<Interface, Implementation>::value, VirtualFunctionBase, FunctionBase>::Type type;
00093   };
00094 
00095 
00096 
00097   // -----------------------------------------------------------------
00098   // Basis
00099   // -----------------------------------------------------------------
00100 
00101 // current versions of doxygen (<= 1.6.2) enter an infinite loop when parsing
00102 // the following class
00103 #ifndef DOXYGEN
00104 
00118   template<class T>
00119   class LocalBasisVirtualInterfaceBase :
00120     public virtual LocalBasisVirtualInterface<typename LowerOrderLocalBasisTraits<T>::Traits>
00121   {
00122     typedef LocalBasisVirtualInterface<typename LowerOrderLocalBasisTraits<T>::Traits> BaseInterface;
00123   public:
00124     typedef T Traits;
00125 
00127     virtual void evaluate (
00128         const typename Dune::template array<int,Traits::diffOrder>& directions,
00129         const typename Traits::DomainType& in,
00130         std::vector<typename Traits::RangeType>& out) const = 0;
00131 
00132     using BaseInterface::evaluate;
00133   };
00134 #endif // DOXYGEN
00135 
00142   template<class DF, int n, class D, class RF, int m, class R, class J>
00143   class LocalBasisVirtualInterfaceBase<LocalBasisTraits<DF,n,D,RF,m,R,J,0> >
00144   {
00145   public:
00146     typedef LocalBasisTraits<DF,n,D,RF,m,R,J,0> Traits;
00147 
00148     virtual ~LocalBasisVirtualInterfaceBase() {}
00149 
00151     virtual unsigned int size () const = 0;
00152 
00154     virtual unsigned int order () const = 0;
00155 
00161     virtual void evaluateFunction (const typename Traits::DomainType& in,
00162         std::vector<typename Traits::RangeType>& out) const = 0;
00163 
00171     virtual void evaluateJacobian(const typename Traits::DomainType& in,         // position
00172                                   std::vector<typename Traits::JacobianType>& out) const = 0;
00173 
00175     virtual void evaluate (
00176         const typename Dune::template array<int,Traits::diffOrder>& directions,
00177         const typename Traits::DomainType& in,
00178         std::vector<typename Traits::RangeType>& out) const = 0;
00179 
00180   };
00181 
00191   template<class T>
00192   class LocalBasisVirtualInterface :
00193     public virtual LocalBasisVirtualInterfaceBase<T>
00194   {
00195     typedef LocalBasisVirtualInterfaceBase<T> BaseInterface;
00196   public:
00197     typedef T Traits;
00198 
00200     template <int k>
00201     void evaluate (
00202         const typename Dune::template array<int,k>& directions,
00203         const typename Traits::DomainType& in,
00204         std::vector<typename Traits::RangeType>& out) const
00205     {
00206       typedef LocalBasisVirtualInterfaceBase<typename FixedOrderLocalBasisTraits<T,k>::Traits > OrderKBaseInterface;
00207       const OrderKBaseInterface& asBase = *this;
00208       asBase.evaluate(directions, in, out);
00209     }
00210 
00211     using BaseInterface::size;
00212     using BaseInterface::order;
00213     using BaseInterface::evaluateFunction;
00214     using BaseInterface::evaluateJacobian;
00215     /* Unfortunately, the intel compiler cannot use the different evaluate
00216      * methods with varying argument lists. :-( */
00217 #ifndef __INTEL_COMPILER
00218     using BaseInterface::evaluate;
00219 #endif
00220   };
00221 
00222 
00223 
00224 
00225   // -----------------------------------------------------------------
00226   // Interpolation
00227   // -----------------------------------------------------------------
00228 
00241   template<class DomainType, class RangeType>
00242   class LocalInterpolationVirtualInterfaceBase
00243   {
00244   public:
00245 
00247     typedef Dune::VirtualFunction<DomainType, RangeType> FunctionType;
00248 
00250     typedef typename RangeType::field_type CoefficientType;
00251 
00252     virtual ~LocalInterpolationVirtualInterfaceBase() {}
00253 
00261     virtual void interpolate (const FunctionType& f, std::vector<CoefficientType>& out) const = 0;
00262   };
00263 
00271   template<class DomainType, class RangeType>
00272   class LocalInterpolationVirtualInterface
00273     : public LocalInterpolationVirtualInterfaceBase<DomainType, RangeType>
00274   {
00275   public:
00276 
00278     typedef Dune::VirtualFunction<DomainType, RangeType> FunctionType;
00279 
00281     typedef typename RangeType::field_type CoefficientType;
00282 
00283 
00284     virtual ~LocalInterpolationVirtualInterface() {}
00285 
00286     // This method is only notet again for to make the documentation complete.
00287 
00295     virtual void interpolate (const FunctionType& f, std::vector<CoefficientType>& out) const = 0;
00296 
00299     template<class F>
00300     void interpolate (const F& f, std::vector<CoefficientType>& out) const
00301     {
00302       const LocalInterpolationVirtualInterfaceBase<DomainType, RangeType>& asBase = *this;
00303       asBase.interpolate(VirtualFunctionWrapper<F>(f),out);
00304     }
00305 
00306     template<class F, class C>
00307     void interpolate (const F& f, std::vector<C>& out) const
00308     {
00309       std::vector<CoefficientType> outDummy;
00310       const LocalInterpolationVirtualInterfaceBase<DomainType, RangeType>& asBase = *this;
00311       asBase.interpolate(VirtualFunctionWrapper<F>(f),outDummy);
00312       out.resize(outDummy.size());
00313       for(int i=0; i<outDummy.size(); ++i)
00314         out[i] = outDummy[i];
00315     }
00316 
00317   private:
00318 
00319     template <typename F>
00320     struct VirtualFunctionWrapper
00321       : public FunctionType
00322     {
00323     public:
00324       VirtualFunctionWrapper(const F &f)
00325         : f_(f)
00326       {}
00327 
00328       virtual ~VirtualFunctionWrapper() {}
00329 
00330       virtual void evaluate(const DomainType& x, RangeType& y) const
00331       {
00332         f_.evaluate(x,y);
00333       }
00334 
00335       const F &f_;
00336     };
00337   };
00338 
00339 
00340 
00341   // -----------------------------------------------------------------
00342   // Coefficients
00343   // -----------------------------------------------------------------
00344 
00350   class LocalCoefficientsVirtualInterface
00351   {
00352   public:
00353 
00354     virtual ~LocalCoefficientsVirtualInterface() {}
00355 
00357     virtual std::size_t size () const = 0;
00358 
00360     const virtual LocalKey& localKey (std::size_t i) const = 0;
00361 
00362   };
00363 
00364 
00365 
00366   // -----------------------------------------------------------------
00367   // Finite Element
00368   // -----------------------------------------------------------------
00369 
00376   template<class T>
00377   class LocalFiniteElementVirtualInterface
00378     : public virtual LocalFiniteElementVirtualInterface<typename LowerOrderLocalBasisTraits<T>::Traits >
00379   {
00380     typedef LocalFiniteElementVirtualInterface<typename LowerOrderLocalBasisTraits<T>::Traits > BaseInterface;
00381 
00382   public:
00383     typedef LocalFiniteElementTraits<
00384       LocalBasisVirtualInterface<T>,
00385       LocalCoefficientsVirtualInterface,
00386       LocalInterpolationVirtualInterface<
00387         typename T::DomainType,
00388         typename T::RangeType> > Traits;
00389 
00391     virtual const typename Traits::LocalBasisType& localBasis () const = 0;
00392 
00393     using BaseInterface::localBasis;
00394     using BaseInterface::localCoefficients;
00395     using BaseInterface::localInterpolation;
00396     using BaseInterface::type;
00397 
00398     virtual LocalFiniteElementVirtualInterface<T>* clone() const = 0;
00399   };
00400 
00401 
00408   template<class DF, int n, class D, class RF, int m, class R, class J>
00409   class LocalFiniteElementVirtualInterface<LocalBasisTraits<DF,n,D,RF,m,R,J,0> >
00410   {
00411     typedef LocalBasisTraits<DF,n,D,RF,m,R,J,0> T;
00412 
00413   public:
00414     typedef LocalFiniteElementTraits<
00415       LocalBasisVirtualInterface<T>,
00416       LocalCoefficientsVirtualInterface,
00417       LocalInterpolationVirtualInterface<
00418         typename T::DomainType,
00419         typename T::RangeType> > Traits;
00420 
00421     virtual ~LocalFiniteElementVirtualInterface() {}
00422 
00424     virtual const typename Traits::LocalBasisType& localBasis () const = 0;
00425 
00427     virtual const typename Traits::LocalCoefficientsType& localCoefficients () const = 0;
00428 
00430     virtual const typename Traits::LocalInterpolationType& localInterpolation () const = 0;
00431 
00433     virtual const GeometryType type () const = 0;
00434 
00435     virtual LocalFiniteElementVirtualInterface<T>* clone() const = 0;
00436   };
00437 
00438 }
00439 #endif