BasisFunction.h 11.2 KB
Newer Older
1 2 3 4
// ============================================================================
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
5
// ==  http://www.amdis-fem.org                                              ==
6 7
// ==                                                                        ==
// ============================================================================
8 9 10 11 12 13 14 15 16 17 18 19
//
// Software License for AMDiS
//
// Copyright (c) 2010 Dresden University of Technology 
// All rights reserved.
// Authors: Simon Vey, Thomas Witkowski et al.
//
// This file is part of AMDiS
//
// See also license.opensource.txt in the distribution.


20 21 22 23 24 25 26

/** \file BasisFunction.h */

#ifndef AMDIS_BASISFUNCTION_H
#define AMDIS_BASISFUNCTION_H

#include <string>
27
#include "AMDiS_fwd.h"
28 29
#include "Global.h"
#include "Boundary.h"
Thomas Witkowski's avatar
Thomas Witkowski committed
30
#include "MatrixVector.h"
31
#include "FixVec.h"
32 33 34

namespace AMDiS {

35 36
  using namespace std;

37
  /// Function interface for evaluating basis functions.
38 39 40
  class BasFctType
  {
  public:
41
    BasFctType() {}
42

43
    virtual ~BasFctType() {}
44 45 46 47

    virtual double operator()(const DimVec<double>&) const = 0;
  };

48

49
  /// Function interface for evaluating gradients of basis functions. 
50 51 52
  class GrdBasFctType
  {
  public:
53
    GrdBasFctType() {}
54

55
    virtual ~GrdBasFctType() {}
56

57 58
    virtual void operator()(const DimVec<double>&, 
			    mtl::dense_vector<double>&) const = 0;
59 60
  };
  
61

62
  /// Function interface for evaluating second derivative of basis functions.
63 64 65
  class D2BasFctType
  {
  public:
66
    D2BasFctType() {}
67

68
    virtual ~D2BasFctType() {}
69

70
    virtual void operator()(const DimVec<double>&, DimMat<double>&) const = 0;
71
  };
72

73
			    
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
  typedef BasFctType *BFptr;
  typedef GrdBasFctType *GBFptr;
  typedef D2BasFctType *DBFptr;

  /** \ingroup FEMSpace
   * \brief
   * Base class for finite element basis functions. In order to build up a
   * finite element space, we have to specify a set of local basis functions.
   * Together with the correspondig DOF administration and the underlying mesh,
   * the finite element space is given. 
   * This class holds the local basis functions and their derivatives of the
   * reference element. They are evaluated at barycentric coordinates, so they
   * can be used on every element of the mesh.  
   */
  class BasisFunction
  {  
  protected:
91
    /// Creates a BasisFunction object of given dim and degree 
92
    BasisFunction(string name, int dim, int degree);
93

94
    /// destructor
95 96 97
    virtual ~BasisFunction();

  public:
98
    /// compares two BasisFunction objects.
Thomas Witkowski's avatar
Thomas Witkowski committed
99 100
    virtual bool operator==(const BasisFunction& a) const 
    {
101
      return a.getName() == name;
102
    }
103

104
    /// Returns !(*this == b)
Thomas Witkowski's avatar
Thomas Witkowski committed
105 106
    inline bool operator!=(const BasisFunction& b) const 
    {
107
      return !(operator == (b));
108
    }
109

110
    /// Used by \ref getDOFIndices and \ref getVec
111 112 113 114
    virtual int* orderOfPositionIndices(const Element* el, GeoIndex position, 
					int positionIndex) const = 0;

    /** \brief
Thomas Witkowski's avatar
Thomas Witkowski committed
115 116 117 118 119 120 121 122 123
     * The second argument 'bound' has to be a pointer to a vector which has 
     * to be filled. Its length is \ref nBasFcts (the number of basis functions
     * in the used finite element space). After calling this function, the i-th 
     * entry of the array is the boundary type of the i-th basis function of this
     * element.
     * 
     * This function needs boundary information within the ElInfo object; thus, 
     * all routines using this function on the elements need the FILL_BOUND 
     * flag during mesh traversal;
124
     */
125
    virtual void getBound(const ElInfo*, BoundaryType *) const {}
126

Thomas Witkowski's avatar
Thomas Witkowski committed
127
    /// Returns \ref degree of BasisFunction
128
    inline int getDegree() const 
Thomas Witkowski's avatar
Thomas Witkowski committed
129
    { 
130
      return degree; 
131
    }
132

Thomas Witkowski's avatar
Thomas Witkowski committed
133
    /// Returns \ref dim of BasisFunction
134
    inline int getDim() const 
Thomas Witkowski's avatar
Thomas Witkowski committed
135
    { 
136
      return dim; 
137
    }
138

Thomas Witkowski's avatar
Thomas Witkowski committed
139
    /// Returns \ref nBasFcts which is the number of local basis functions
140
    inline int getNumber() const 
Thomas Witkowski's avatar
Thomas Witkowski committed
141
    { 
142
      return nBasFcts; 
143
    }
144

Thomas Witkowski's avatar
Thomas Witkowski committed
145
    /// Returns \ref name of BasisFunction
146
    inline string getName() const 
Thomas Witkowski's avatar
Thomas Witkowski committed
147
    { 
148
      return name; 
149
    }
150

Thomas Witkowski's avatar
Thomas Witkowski committed
151
    /// Returns \ref nDOF[i]
152
    int getNumberOfDofs(int i) const;
153

Thomas Witkowski's avatar
Thomas Witkowski committed
154
    /// Returns \ref nDOF
155
    inline DimVec<int>* getNumberOfDofs() const 
Thomas Witkowski's avatar
Thomas Witkowski committed
156
    { 
157
      return nDOF; 
158
    }
159

Thomas Witkowski's avatar
Thomas Witkowski committed
160
    /// Initialisation of the \ref nDOF vector. Must be implemented by sub classes
161 162
    virtual void setNDOF() = 0;

Thomas Witkowski's avatar
Thomas Witkowski committed
163
    /// Returns the barycentric coordinates of the i-th basis function.
164 165 166
    virtual DimVec<double> *getCoords(int i) const = 0;

    /** \brief
167
     * Fills a vector with interpolation coefficients of the
168 169 170 171 172 173 174 175
     * function f; if indices is a pointer to NULL, the coefficient for all 
     * basis functions are calculated and the i-th entry in the vector is the 
     * coefficient of the i-th basis function; if indices is non NULL, only the 
     * coefficients for a subset of the local basis functions has to be 
     * calculated; n is the number of those basis functions, indices[0], . . . 
     * , indices[n-1] are the local indices of the basis functions where the
     * coefficients have to be calculated, and the i-th entry in the return 
     * vector is then the coefficient of the indices[i]-th basis function; coeff 
Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
176
     * may be a pointer to a vector which has to be filled.
177 178 179 180 181
     * such a function usually needs vertex coordinate information; thus, all 
     * routines using this function on the elements need the FILL COORDS flag 
     * during mesh traversal.
     * Must be implemented by sub classes.
     */
182 183 184 185 186
    virtual void interpol(const ElInfo *el_info, 
			  int n, 
			  const int *indices, 
			  AbstractFunction<double, WorldVector<double> > *f,
			  mtl::dense_vector<double> &coeff) const = 0;
187

188
    /// WorldVector<double> valued interpol function.
189 190 191 192 193
    virtual void interpol(const ElInfo *el_info, 
			  int no, 
			  const int *b_no,
			  AbstractFunction<WorldVector<double>, WorldVector<double> > *f, 
			  mtl::dense_vector<WorldVector<double> >& coeff) const = 0;
194

195
    /// Returns the i-th local basis function
Thomas Witkowski's avatar
Thomas Witkowski committed
196 197
    inline BasFctType *getPhi(int i) const 
    { 
198
      return (*phi)[i]; 
199
    }
200

201
    /// Returns the gradient of the i-th local basis function
Thomas Witkowski's avatar
Thomas Witkowski committed
202 203
    inline GrdBasFctType *getGrdPhi(int i) const 
    { 
204
      return (*grdPhi)[i]; 
205
    }
206

207
    /// Returns the second derivative of the i-th local basis function
Thomas Witkowski's avatar
Thomas Witkowski committed
208 209
    inline D2BasFctType *getD2Phi(int i) const 
    { 
210
      return (*d2Phi)[i]; 
211
    }
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234

    /** \brief
     * Approximates the L2 scalar products of a given function with all basis 
     * functions by numerical quadrature and adds the corresponding values to a 
     * DOF vector;
     * f is a pointer for the evaluation of the given function in world 
     * coordinates x and returns the value of that function at x; if f is a NULL
     *  pointer, nothing is done;
     * fh is the DOF vector where at the i-th entry the approximation of the L2 
     * scalar product of the given function with the i-th global basis function 
     * of fh->feSpace is stored;
     * quad is the quadrature for the approximation of the integral on each leaf 
     * element of fh->feSpace->mesh; if quad is a NULL pointer, a default 
     * quadrature which is exact of degree 2*fh->feSpace->basFcts->degree-2 is 
     * used.
     * The integrals are approximated by looping over all leaf elements, 
     * computing the approximations to the element contributions and adding 
     * these values to the vector fh by add element vec().
     * The vector fh is not initialized with 0.0; only the new contributions are 
     * added
     */
    virtual void l2ScpFctBas(Quadrature*,
			     AbstractFunction<double, WorldVector<double> >* /*f*/,
235 236
			     DOFVector<double>* /*fh*/)
    {}
237

238
    /// WorldVector<double> valued l2ScpFctBas function
239 240
    virtual void l2ScpFctBas(Quadrature* ,
			     AbstractFunction<WorldVector<double>, WorldVector<double> >* /*f*/,
241 242
			     DOFVector<WorldVector<double> >* /*fh*/) 
    {}
243 244


245 246
    /// Interpolates a DOFIndexed<double> after refinement
    virtual void refineInter(DOFIndexed<double> *, RCNeighbourList*, int)
247
    {}
248

249 250
    /// Interpolates a DOFIndexed<double> after coarsening
    virtual void coarseInter(DOFIndexed<double> *, RCNeighbourList*, int)
251
    {}
252

253 254
    /// Restricts a DOFIndexed<double> after coarsening
    virtual void coarseRestr(DOFIndexed<double> *, RCNeighbourList*, int)
255
    {}
256

257 258
    /// Interpolates a DOFVector<WorldVector<double> > after refinement
    virtual void refineInter(DOFVector<WorldVector<double> >*, RCNeighbourList*, int)
259
    {}
260

261 262
    /// Interpolates a DOFVector<WorldVector<double> > after coarsening
    virtual void coarseInter(DOFVector<WorldVector<double> >*, RCNeighbourList*, int)
263
    {}
264

265 266
    /// Restricts a DOFVector<WorldVector<double> > after coarsening
    virtual void coarseRestr(DOFVector<WorldVector<double> >*, RCNeighbourList*, int)
267
    {}
268

269
    /// Returns local dof indices of the element for the given fe space.
Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
270 271 272 273
    virtual void getLocalIndices(const Element *el,
				 const DOFAdmin *admin,
				 vector<DegreeOfFreedom> &indices) const
    {}
Thomas Witkowski's avatar
Thomas Witkowski committed
274

Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
275
    ///
Thomas Witkowski's avatar
Thomas Witkowski committed
276 277
    virtual void getLocalDofPtrVec(const Element *el, 
				   const DOFAdmin *admin,
278
				   vector<const DegreeOfFreedom*>& vec) const
279
    {}
Thomas Witkowski's avatar
Thomas Witkowski committed
280

281

Thomas Witkowski's avatar
Blub  
Thomas Witkowski committed
282 283
    /// Evaluates elements value at barycentric coordinates lambda with local 
    /// coefficient vector uh.
284 285
    template<typename T>
    T evalUh(const DimVec<double>& lambda, const mtl::dense_vector<T>& uh) const;
286 287


288 289 290 291 292 293 294
    /** \brief
     * Evaluates the gradient at barycentric coordinates lambda. Lambda is the
     * Jacobian of the barycentric coordinates. uh is the local coefficient
     * vector. If val is not NULL the result will be stored 
     * there, otherwise a pointer to a static local variable is returned which 
     * will be overwritten after the next call.
     */
295 296 297 298 299 300
    template<typename T>
    typename GradientType<T>::type& evalGrdUh(const DimVec<double>& lambda,
					      const DimVec<WorldVector<double> >& Lambda,
					      const mtl::dense_vector<T>& uh,
					      typename GradientType<T>::type& val) const;

301 302 303 304 305 306 307 308 309 310

    /** \brief
     * Evaluates the second derivative at barycentric coordinates lambda. 
     * Lambda is the Jacobian of the barycentric coordinates. uh is the local 
     * coefficient vector. If val is not NULL the result will be stored 
     * there, otherwise a pointer to a static local variable is returned which 
     * will be overwritten after the next call.
     */
    const WorldMatrix<double>& evalD2Uh(const DimVec<double>& lambda,
					const DimVec<WorldVector<double> >& Lambda,
Thomas Witkowski's avatar
Thomas Witkowski committed
311 312
					const ElementVector& uh,
					WorldMatrix<double>* val) const;
313 314

  protected:
315
    /// Textual description
316
    string name;     
317

318
    /// Number of basisfunctions on one Element                 
319 320
    int nBasFcts;

321
    /// Maximal degree of the basis functions                 
322 323
    int degree;

324
    /// Dimension of the basis functions                  
325 326
    int dim;

327
    /// Dimension of the world.
Thomas Witkowski's avatar
Thomas Witkowski committed
328 329
    int dow;

330
    /// Number of DOFs at the different positions                  
331 332
    DimVec<int> *nDOF;

333
    /// Vector of the local functions
334
    vector<BasFctType*> *phi;
335

336
    /// Vector of gradients
337
    vector<GrdBasFctType*> *grdPhi;
338

339
    /// Vector of second derivatives
340
    vector<D2BasFctType*> *d2Phi;
341 342 343
  };

}
344
#include "BasisFunction.hh"
345 346

#endif  // AMDIS_BASISFUNCTION_H