dune-localfunctions  2.2.0
whitney/edges0.5/basis.hh
Go to the documentation of this file.
1 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set ts=8 sw=2 et sts=2:
3 
4 #ifndef DUNE_LOCALFUNCTIONS_WHITNEY_EDGES0_5_BASIS_HH
5 #define DUNE_LOCALFUNCTIONS_WHITNEY_EDGES0_5_BASIS_HH
6 
7 #include <cstddef>
8 #include <vector>
9 
10 #include <dune/common/fmatrix.hh>
11 #include <dune/common/fvector.hh>
12 // #include <dune/common/geometrytype.hh>
13 
14 // #include <dune/grid/common/referenceelements.hh>
15 
16 // #include <dune/localfunctions/common/localkey.hh>
20 
21 namespace Dune {
22 
24  //
25  // Basis
26  //
27 
29 
37  template<class Geometry, class RF>
38  class EdgeS0_5Basis :
39  private EdgeS0_5Common<Geometry::mydimension, typename Geometry::ctype>
40  {
41  public:
43  struct Traits {
44  typedef typename Geometry::ctype DomainField;
45  static const std::size_t dimDomainLocal = Geometry::mydimension;
46  static const std::size_t dimDomainGlobal = Geometry::coorddimension;
47  typedef FieldVector<DomainField, dimDomainLocal> DomainLocal;
48  typedef FieldVector<DomainField, dimDomainGlobal> DomainGlobal;
49 
50  typedef RF RangeField;
51  static const std::size_t dimRange = dimDomainLocal;
52  typedef FieldVector<RangeField, dimRange> Range;
53 
54  typedef FieldMatrix<RangeField, dimRange, dimDomainGlobal> Jacobian;
55 
56  static const std::size_t diffOrder = 1;
57  };
58 
59  private:
60  typedef Dune::P1LocalBasis<typename Traits::DomainField,
61  typename Traits::RangeField,
63  > P1LocalBasis;
65 
66  static const P1LocalBasis& p1LocalBasis;
67  static const std::size_t dim = Traits::dimDomainLocal;
68 
70  using Base::refelem;
71  using Base::s;
72 
73  // global values of the Jacobians (gradients) of the p1 basis
74  std::vector<typename P1Basis::Traits::Jacobian> p1j;
75  // edge sizes and orientations
76  std::vector<typename Traits::DomainField> edgel;
77 
78  public:
80 
86  template<typename VertexOrder>
87  EdgeS0_5Basis(const Geometry& geo, const VertexOrder& vertexOrder) :
88  p1j(s, typename P1Basis::Traits::Jacobian(0)), edgel(s)
89  {
90  // use some arbitrary position to evaluate jacobians, they are constant
91  static const typename Traits::DomainLocal xl(0);
92 
93  // precompute Jacobian (gradients) of the p1 element
94  P1Basis(p1LocalBasis, geo).evaluateJacobian(xl, p1j);
95 
96  // calculate edge sizes and orientations
97  for(std::size_t i = 0; i < s; ++i) {
98  edgel[i] = (geo.corner(refelem.subEntity(i,dim-1,0,dim))-
99  geo.corner(refelem.subEntity(i,dim-1,1,dim))
100  ).two_norm();
101  const typename VertexOrder::iterator& edgeVertexOrder =
102  vertexOrder.begin(dim-1, i);
103  if(edgeVertexOrder[0] > edgeVertexOrder[1])
104  edgel[i] *= -1;
105  }
106  }
107 
109  std::size_t size () const { return s; }
110 
112  void evaluateFunction(const typename Traits::DomainLocal& xl,
113  std::vector<typename Traits::Range>& out) const
114  {
115  out.assign(s, typename Traits::Range(0));
116 
117  // compute p1 values -- use the local basis directly for that, local and
118  // global values are identical for scalars
119  std::vector<typename P1LocalBasis::Traits::RangeType> p1v;
120  p1LocalBasis.evaluateFunction(xl, p1v);
121 
122  for(std::size_t i = 0; i < s; i++) {
123  const std::size_t i0 = refelem.subEntity(i,dim-1,0,dim);
124  const std::size_t i1 = refelem.subEntity(i,dim-1,1,dim);
125  out[i].axpy( p1v[i0], p1j[i1][0]);
126  out[i].axpy(-p1v[i1], p1j[i0][0]);
127  out[i] *= edgel[i];
128  }
129  }
130 
132  void evaluateJacobian(const typename Traits::DomainLocal&,
133  std::vector<typename Traits::Jacobian>& out) const
134  {
135  out.resize(s);
136 
137  for(std::size_t i = 0; i < s; i++) {
138  const std::size_t i0 = refelem.subEntity(i,dim-1,0,dim);
139  const std::size_t i1 = refelem.subEntity(i,dim-1,1,dim);
140  for(std::size_t j = 0; j < dim; j++)
141  for(std::size_t k = 0; k < dim; k++)
142  out[i][j][k] = edgel[i] *
143  (p1j[i0][0][k]*p1j[i1][0][j]-p1j[i1][0][k]*p1j[i0][0][j]);
144  }
145  }
146 
148  std::size_t order () const { return 1; }
149  };
150 
151  template<class Geometry, class RF>
152  const typename EdgeS0_5Basis<Geometry, RF>::P1LocalBasis&
153  EdgeS0_5Basis<Geometry, RF>::p1LocalBasis = P1LocalBasis();
154 
155 } // namespace Dune
156 
157 #endif // DUNE_LOCALFUNCTIONS_WHITNEY_EDGES0_5_BASIS_HH