Dune Core Modules (2.6.0)

monomiallocalbasis.hh
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_LOCALFUNCTIONS_MONOMIAL_MONOMIALLOCALBASIS_HH
4 #define DUNE_LOCALFUNCTIONS_MONOMIAL_MONOMIALLOCALBASIS_HH
5 
6 #include <array>
7 #include <cassert>
8 #include <numeric>
9 
10 #include <dune/common/fmatrix.hh>
11 
12 #include "../common/localbasis.hh"
13 
14 namespace Dune
15 {
16  namespace MonomImp {
20  template<int d, int k>
21  struct Size {
22  enum { val = Size<d,k-1>::val+Size<d-1,k>::val };
23  };
24  template<int d>
25  struct Size<d, 0> {
26  enum { val = 1 };
27  };
28  template<int k>
29  struct Size<0, k> {
30  enum { val = 1 };
31  };
32  template<>
33  struct Size<0, 0> {
34  enum { val = 1 };
35  };
36 
37  template<class T>
38  T ipow(T base, int exp)
39  {
40  T result(1);
41  while (exp)
42  {
43  if (exp & 1)
44  result *= base;
45  exp >>= 1;
46  base *= base;
47  }
48  return result;
49  }
50 
52  template <typename Traits>
53  class EvalAccess {
54  std::vector<typename Traits::RangeType> &out;
55 #ifndef NDEBUG
56  unsigned int first_unused_index;
57 #endif
58 
59  public:
60  EvalAccess(std::vector<typename Traits::RangeType> &out_)
61  : out(out_)
62 #ifndef NDEBUG
63  , first_unused_index(0)
64 #endif
65  { }
66 #ifndef NDEBUG
67  ~EvalAccess() {
68  assert(first_unused_index == out.size());
69  }
70 #endif
71  typename Traits::RangeFieldType &operator[](unsigned int index)
72  {
73  assert(index < out.size());
74 #ifndef NDEBUG
75  if(first_unused_index <= index)
76  first_unused_index = index+1;
77 #endif
78  return out[index][0];
79  }
80  };
81 
83  template <typename Traits>
85  std::vector<typename Traits::JacobianType> &out;
86  unsigned int row;
87 #ifndef NDEBUG
88  unsigned int first_unused_index;
89 #endif
90 
91  public:
92  JacobianAccess(std::vector<typename Traits::JacobianType> &out_,
93  unsigned int row_)
94  : out(out_), row(row_)
95 #ifndef NDEBUG
96  , first_unused_index(0)
97 #endif
98  { }
99 #ifndef NDEBUG
100  ~JacobianAccess() {
101  assert(first_unused_index == out.size());
102  }
103 #endif
104  typename Traits::RangeFieldType &operator[](unsigned int index)
105  {
106  assert(index < out.size());
107 #ifndef NDEBUG
108  if(first_unused_index <= index)
109  first_unused_index = index+1;
110 #endif
111  return out[index][0][row];
112  }
113  };
114 
127  template <typename Traits, int c>
128  struct Evaluate
129  {
130  enum {
132  d = Traits::dimDomain - c
133  };
140  template <typename Access>
141  static void eval (
142  const typename Traits::DomainType &in,
145  const std::array<int, Traits::dimDomain> &derivatives,
148  typename Traits::RangeFieldType prod,
150  int bound,
152  int& index,
154  Access &access)
155  {
156  // start with the highest exponent for this dimension, then work down
157  for (int e = bound; e >= 0; --e)
158  {
159  // the rest of the available exponents, to be used by the other
160  // dimensions
161  int newbound = bound - e;
162  if(e < derivatives[d])
164  eval(in, derivatives, 0, newbound, index, access);
165  else {
166  int coeff = 1;
167  for(int i = e - derivatives[d] + 1; i <= e; ++i)
168  coeff *= i;
169  // call the evaluator for the next dimension
171  eval( // pass the coordinate and the derivatives unchanged
172  in, derivatives,
173  // also pass the product accumulated so far, but also
174  // include the current dimension
175  prod * ipow(in[d], e-derivatives[d]) * coeff,
176  // pass the number of remaining exponents to the next
177  // dimension
178  newbound,
179  // pass the next index to fill and the output access
180  // wrapper
181  index, access);
182  }
183  }
184  }
185  };
186 
191  template <typename Traits>
192  struct Evaluate<Traits, 1>
193  {
194  enum { d = Traits::dimDomain-1 };
196  template <typename Access>
197  static void eval (const typename Traits::DomainType &in,
198  const std::array<int, Traits::dimDomain> &derivatives,
199  typename Traits::RangeFieldType prod,
200  int bound, int& index, Access &access)
201  {
202  if(bound < derivatives[d])
203  prod = 0;
204  else {
205  int coeff = 1;
206  for(int i = bound - derivatives[d] + 1; i <= bound; ++i)
207  coeff *= i;
208  prod *= ipow(in[d], bound-derivatives[d]) * coeff;
209  }
210  access[index] = prod;
211  ++index;
212  }
213  };
214 
215  } //namespace MonomImp
216 
230  template<class D, class R, unsigned int d, unsigned int p>
232  {
233  public:
237 
239  unsigned int size () const
240  {
242  }
243 
245  inline void evaluateFunction (const typename Traits::DomainType& in,
246  std::vector<typename Traits::RangeType>& out) const
247  {
248  out.resize(size());
249  int index = 0;
250  std::array<int, d> derivatives;
251  std::fill(derivatives.begin(), derivatives.end(), 0);
252  MonomImp::EvalAccess<Traits> access(out);
253  for (unsigned int lp = 0; lp <= p; ++lp)
254  MonomImp::Evaluate<Traits, d>::eval(in, derivatives, 1, lp, index, access);
255  }
256 
262  inline void partial(const std::array<unsigned int,d>& order,
263  const typename Traits::DomainType& in,
264  std::vector<typename Traits::RangeType>& out) const
265  {
266  out.resize(size());
267  int index = 0;
268  std::array<int, d> derivatives; // We need 'order' array as a signed int array
269  std::copy(order.begin(), order.end(), derivatives.begin());
270  MonomImp::EvalAccess<Traits> access(out);
271  for (unsigned int lp = 0; lp <= p; ++lp)
272  MonomImp::Evaluate<Traits, d>::eval(in, derivatives, 1, lp, index, access);
273  }
274 
276  inline void
277  evaluateJacobian (const typename Traits::DomainType& in, // position
278  std::vector<typename Traits::JacobianType>& out) const // return value
279  {
280  out.resize(size());
281  std::array<int, d> derivatives;
282  for(unsigned int i = 0; i < d; ++i)
283  derivatives[i] = 0;
284  for(unsigned int i = 0; i < d; ++i)
285  {
286  derivatives[i] = 1;
287  int index = 0;
288  MonomImp::JacobianAccess<Traits> access(out, i);
289  for(unsigned int lp = 0; lp <= p; ++lp)
290  MonomImp::Evaluate<Traits, d>::eval(in, derivatives, 1, lp, index, access);
291  derivatives[i] = 0;
292  }
293  }
294 
296  unsigned int order () const
297  {
298  return p;
299  }
300  };
301 
302 }
303 
304 #endif // DUNE_LOCALFUNCTIONS_MONOMIAL_MONOMIALLOCALBASIS_HH
A dense n x m matrix.
Definition: fmatrix.hh:68
vector space out of a tensor product of fields.
Definition: fvector.hh:93
Access output vector of evaluateFunction() and evaluate()
Definition: monomiallocalbasis.hh:53
Access output vector of evaluateJacobian()
Definition: monomiallocalbasis.hh:84
Constant shape function.
Definition: monomiallocalbasis.hh:232
unsigned int size() const
number of shape functions
Definition: monomiallocalbasis.hh:239
unsigned int order() const
Polynomial order of the shape functions.
Definition: monomiallocalbasis.hh:296
void partial(const std::array< unsigned int, d > &order, const typename Traits::DomainType &in, std::vector< typename Traits::RangeType > &out) const
Evaluate partial derivatives of any order of all shape functions.
Definition: monomiallocalbasis.hh:262
void evaluateJacobian(const typename Traits::DomainType &in, std::vector< typename Traits::JacobianType > &out) const
Evaluate Jacobian of all shape functions.
Definition: monomiallocalbasis.hh:277
void evaluateFunction(const typename Traits::DomainType &in, std::vector< typename Traits::RangeType > &out) const
Evaluate all shape functions.
Definition: monomiallocalbasis.hh:245
LocalBasisTraits< D, d, Dune::FieldVector< D, d >, R, 1, Dune::FieldVector< R, 1 >, Dune::FieldMatrix< R, 1, d > > Traits
export type traits for function signature
Definition: monomiallocalbasis.hh:236
Implements a matrix constructed from a given type representing a field and compile-time given number ...
Dune namespace.
Definition: alignedallocator.hh:10
Type traits for LocalBasisVirtualInterface.
Definition: localbasis.hh:32
D DomainType
domain type
Definition: localbasis.hh:43
static void eval(const typename Traits::DomainType &in, const std::array< int, Traits::dimDomain > &derivatives, typename Traits::RangeFieldType prod, int bound, int &index, Access &access)
Definition: monomiallocalbasis.hh:197
Definition: monomiallocalbasis.hh:129
@ d
The next dimension to try for factors.
Definition: monomiallocalbasis.hh:132
static void eval(const typename Traits::DomainType &in, const std::array< int, Traits::dimDomain > &derivatives, typename Traits::RangeFieldType prod, int bound, int &index, Access &access)
Definition: monomiallocalbasis.hh:141
Definition: monomiallocalbasis.hh:21
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 2, 22:35, 2024)