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
00074
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
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 ); ;
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 }
00413
00414
00415 #endif // DUNE_MONOMIALSHAPEFUNCTIONS_HH