monomialshapefunctions.hh

Go to the documentation of this file.
00001 #ifndef DUNE_MONOMIALSHAPEFUNCTIONS_HH
00002 #define DUNE_MONOMIALSHAPEFUNCTIONS_HH
00003 
00004 #include <iostream>
00005 #include <vector>
00006 
00007 #include <dune/common/fvector.hh>
00008 #include <dune/common/exceptions.hh>
00009 #include <dune/common/stdstreams.hh>
00010 #include <dune/common/misc.hh>
00011 #include <dune/grid/common/grid.hh>
00012 
00013 #include <dune/disc/shapefunctions/shapefunctions.hh>
00014 
00021 namespace Dune
00022 {
00023 
00029   enum {
00034     MonomialShapeFunctionDefaultMaxOrder = 5
00035   };
00036 
00037   template<typename C,typename T, int dim>
00038   class MonomialShapeFunction;
00039   template<typename C,typename T, int dim>
00040   class MonomialShapeFunctionSet;
00041   template<typename C,typename T, int dim,
00042            int maxOrder=MonomialShapeFunctionDefaultMaxOrder>
00043   class MonomialShapeFunctionSetContainer;
00044 
00050   template<typename C,typename T, int d>
00051   class MonomialShapeFunction : public ShapeFunction<C,T,d,1>
00052   {
00053   public:
00054     enum { dim=d  };
00055     typedef C CoordType;
00056     typedef T ResultType;
00057     
00065     MonomialShapeFunction(int n, const FieldVector<int, dim> & exp):
00066       n_(n), exp_(exp) {}
00067     
00069     virtual ResultType
00070     evaluateFunction (int, const FieldVector<CoordType,dim>& x) const
00071       {
00072         ResultType phi = 1.0;
00073         // phi= x^(alpha-beta) * y^beta
00074         // The compiler should be able to eliminate this loop
00075         for (int c=0; c<dim; c++)
00076         {
00077           phi *= power(x[c],exp_[c]);
00078         }
00079         return phi;
00080       } 
00081 
00083     virtual ResultType
00084     evaluateDerivative(int, int dir, const FieldVector<CoordType,dim>& x) const
00085       { 
00086         ResultType dphi = 1.0;
00087         // The compiler should be able to eliminate this loop
00088         for (int c=0; c<dim; c++)
00089         {
00090           if (c==dir)
00091             dphi *= exp_[c] * power(x[c],exp_[c]-1);
00092           else
00093             dphi *= power(x[c],exp_[c]);
00094         }
00095         return dphi;
00096       }
00097 
00099     virtual int localindex (int comp) const { return n_; };
00100 
00102     virtual int codim () const { return 0; };
00103 
00105     virtual int entity () const { return 0; };
00106 
00108     virtual int entityindex () const { return 0; };
00109 
00111     void print (std::ostream& s) const
00112     {
00113       static const char names[] =
00114         { 'x', 'y', 'z', 'u', 'v', 'w', 'q', 'r', 's' };
00115       assert( dim < 9 ); /* avoid buffer overrun un names */;
00116       bool all_zero = true;
00117       for (int c=0; c<dim; c++)
00118       {
00119         if (exp_[c] > 0) {
00120           if (exp_[c] == 1) {
00121             s << names[c] << " ";
00122           }
00123           else {
00124             s << names[c] << "^" << exp_[c] << " ";
00125           }
00126           all_zero = false;
00127         }
00128       }
00129       if (all_zero) {
00130         s << 1 <<" ";
00131       }
00132     };
00133   private:
00135     int n_;
00137     FieldVector<int, dim> exp_;
00139     ResultType power(CoordType x, int p) const {
00140       if (p <= 0)
00141         return 1.0;
00142       return x*power(x, p-1);
00143     }
00144   };
00145 
00146   template<typename C,typename T, int d>
00147   inline std::ostream& operator<<(std::ostream& os,
00148                                   const MonomialShapeFunction<C,T,d>& s)
00149   {
00150     s.print(os);
00151     return os;
00152   }
00153   
00160   template <typename C,typename T, int dim, int c>
00161   struct MonomialShapeFunctionSetCreator
00162   {
00163     typedef MonomialShapeFunction<C,T,dim> ShapeFunction;
00164     typedef FieldVector<int, dim> expV;
00165     typedef std::vector< ShapeFunction* > sfV;
00166     static void create (int bound, int& cnt, expV& exp, sfV& SFnts)
00167       {
00168         for (int a=0; a<=bound; a++)
00169         {
00170           exp[c-1] = bound-a;
00171           MonomialShapeFunctionSetCreator<C,T,dim,c+1>::create(a,cnt,exp,SFnts);
00172         }
00173       }
00174   };
00175   
00181   template <typename C,typename T, int dim>
00182   struct MonomialShapeFunctionSetCreator<C,T,dim,0>
00183   {
00184     typedef MonomialShapeFunction<C,T,dim> ShapeFunction;
00185     typedef FieldVector<int, dim> expV;
00186     typedef std::vector< ShapeFunction* > sfV;
00187     static int create (int order, sfV& SFnts)
00188       {
00189         expV exp(0);
00190         int cnt = 0;
00191         for (int a=0; a<=order; a++)
00192         {
00193           MonomialShapeFunctionSetCreator<C,T,dim,1>::create(a,cnt,exp,SFnts);
00194         }
00195         return cnt;
00196       }
00197   };
00198   
00204   template <typename C,typename T, int dim>
00205   struct MonomialShapeFunctionSetCreator<C,T,dim,dim>
00206   {
00207     typedef MonomialShapeFunction<C,T,dim> ShapeFunction;
00208     typedef FieldVector<int, dim> expV;
00209     typedef std::vector< ShapeFunction* > sfV;
00210     static void create (int bound, int& cnt, expV& exp, sfV& SFnts)
00211       {
00212           exp[dim-1] = bound;
00213           SFnts[cnt] = new ShapeFunction(cnt, exp);
00214           for (int i=0; i<dim; i++)
00215             dvverb << exp[i] << " ";
00216           dvverb << std::endl;
00217           cnt++;
00218       }
00219   };
00220   
00236   template<typename C,typename T, int d>
00237   class MonomialShapeFunctionSet : public ShapeFunctionSet<C, T, d, 1>
00238   {
00239   public:
00240     enum { dim=d  };
00241     typedef C CoordType;
00242     typedef T ResultType;
00243     typedef MonomialShapeFunction<C,T,dim> ShapeFunction;
00244 
00248     MonomialShapeFunctionSet(int order):
00249       order_(order), n_(sz(order)), shapeFunctions(n_)
00250       {
00251         dvverb << "Constructing monomial shape function set of order "
00252                << order << std::endl;
00253 #ifndef  NDEBUG
00254         size_t i =
00255 #endif
00256           MonomialShapeFunctionSetCreator<C,T,dim,0>::
00257           create(order,shapeFunctions);
00258         assert (n_==i);
00259       }
00260 
00261     virtual ~MonomialShapeFunctionSet()
00262       {
00263         for (size_t i=0; i < n_; i++)
00264         {
00265           if (shapeFunctions[i]) delete shapeFunctions[i];
00266         }
00267       }
00268 
00270     virtual int size() const
00271       {
00272         assert(shapeFunctions.size() == n_);
00273         return n_;
00274       }
00275 
00277     virtual int size (int entity, int codim) const
00278       {
00279         if (codim == 0) return n_;
00280         return 0;
00281       };
00282 
00284     virtual const ShapeFunction& operator[](int i) const
00285       {
00286         assert (i < (int)n_);
00287         assert (n_ == shapeFunctions.size());
00288         return *shapeFunctions[i];
00289       }
00290 
00292     virtual int order() const
00293       {
00294         return order_;
00295       }
00296 
00298     virtual GeometryType type () const
00299       {
00301         static GeometryType t(GeometryType::cube, d);
00302         return t;
00303       };
00304     
00305   private:
00307     const int order_;
00309     const size_t n_;
00311     static int sz(int order)
00312       {
00313         int s;
00314         s = 1;
00315         for (int i=1; i<=dim; i++) {
00316           s = s * (order + i) / i;
00317         }
00318         return s;
00319       }
00321     std::vector< ShapeFunction* > shapeFunctions;
00322   };
00323 
00329   template <int dim, int order>
00330   struct MonomialShapeFunctionSetSize
00331   {
00332     enum
00333     {
00334       maxSize =
00335       MonomialShapeFunctionSetSize<dim-1,order>::maxSize
00336       * (order+dim) / dim
00337     };
00338   };
00339 
00345   template <int order>
00346   struct MonomialShapeFunctionSetSize<1,order>
00347   {
00348     enum { maxSize = order + 1 };
00349   };
00350 
00365   template<typename C,typename T, int d, int maxOrder>
00366   class MonomialShapeFunctionSetContainer :
00367     public ShapeFunctionSetContainer<C,T,d,1,MonomialShapeFunctionSetSize<d,maxOrder>::maxSize >
00368   {
00369   public:
00370     enum { dim = d  };
00371     enum { maxsize = MonomialShapeFunctionSetSize<d,maxOrder>::maxSize };
00372     typedef C CoordType; 
00373     typedef T ResultType;
00374     typedef MonomialShapeFunctionSet<C,T,dim> ShapeFunctionSet;
00375 
00379     MonomialShapeFunctionSetContainer() :
00380       shapeFunctionSets(maxsize)
00381       {
00382         for (int order=0; order<=maxOrder; order++)
00383         {
00384           shapeFunctionSets[order] =
00385             new ShapeFunctionSet(order);
00386         }
00387                 for (int order=maxOrder+1; order<maxsize; order++)
00388           shapeFunctionSets[order] = 0;
00389       }
00390 
00391     virtual ~MonomialShapeFunctionSetContainer()
00392       {
00393         for (int i=0; i < maxsize; i++)
00394         {
00395           if (shapeFunctionSets[i]) delete shapeFunctionSets[i];
00396         }
00397       }
00398 
00400         virtual const ShapeFunctionSet& operator() (GeometryType type, int order) const
00401       {
00402         assert(order <= maxOrder);
00403         return *shapeFunctionSets[order];
00404       }
00405   private:
00407     std::vector< ShapeFunctionSet* > shapeFunctionSets;
00408   };
00409 
00412 }//end of namespace
00413 
00414   
00415 #endif // DUNE_MONOMIALSHAPEFUNCTIONS_HH

Generated on 6 Jan 2009 with Doxygen (ver 1.5.1) [logfile].