dune-functions  2.6-dev
discreteglobalbasisfunction.hh
Go to the documentation of this file.
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_FUNCTIONS_GRIDFUNCTIONS_DISCRETEGLOBALBASISFUNCTIONS_HH
4 #define DUNE_FUNCTIONS_GRIDFUNCTIONS_DISCRETEGLOBALBASISFUNCTIONS_HH
5 
6 #include <memory>
7 
8 #include <dune/common/shared_ptr.hh>
9 
15 
16 namespace Dune {
17 namespace Functions {
18 
19 
20 
66 template<typename B, typename TP, typename V,
67  typename NTRE = DefaultNodeToRangeMap<typename std::decay<decltype(std::declval<B>().localView().tree().child(std::declval<TP>()))>::type>,
68  typename R = typename V::value_type>
70 {
71 public:
72  using Basis = B;
73  using TreePath = TP;
74  using Vector = V;
75 
76  using GridView = typename Basis::GridView;
78  using Tree = typename Basis::LocalView::Tree;
79  using SubTree = typename TypeTree::ChildForTreePath<Tree, TreePath>;
80  using NodeToRangeEntry = NTRE;
81 
83  using Range = R;
84 
86  using Element = typename EntitySet::Element;
87 
88  using Traits = Imp::GridFunctionTraits<Range(Domain), EntitySet, DefaultDerivativeTraits, 16>;
89 
91  {
92  using LocalBasisView = typename Basis::LocalView;
93  using LocalIndexSet = typename Basis::LocalIndexSet;
94  using size_type = typename SubTree::size_type;
95 
96  template<class Node>
97  using LocalBasisRange = typename Node::FiniteElement::Traits::LocalBasisType::Traits::RangeType;
98 
99  template<class Node>
100  using NodeData = typename std::vector<LocalBasisRange<Node>>;
101 
103 
104  struct LocalEvaluateVisitor
105  : public TypeTree::TreeVisitor
106  , public TypeTree::DynamicTraversal
107  {
108  LocalEvaluateVisitor(const LocalDomain& x, Range& y, const LocalIndexSet& localIndexSet, const Vector& coefficients, const NodeToRangeEntry& nodeToRangeEntry, ShapeFunctionValueContainer& shapeFunctionValueContainer):
109  x_(x),
110  y_(y),
111  localIndexSet_(localIndexSet),
112  coefficients_(coefficients),
113  nodeToRangeEntry_(nodeToRangeEntry),
114  shapeFunctionValueContainer_(shapeFunctionValueContainer)
115  {}
116 
117  template<typename Node, typename TreePath>
118  void leaf(Node& node, TreePath treePath)
119  {
120  using LocalBasisRange = typename Node::FiniteElement::Traits::LocalBasisType::Traits::RangeType;
121  using MultiIndex = typename LocalIndexSet::MultiIndex;
122  using CoefficientBlock = typename std::decay<decltype(std::declval<Vector>()[std::declval<MultiIndex>()])>::type;
123  using RangeBlock = typename std::decay<decltype(nodeToRangeEntry_(node, y_))>::type;
124 
125  auto&& fe = node.finiteElement();
126  auto&& localBasis = fe.localBasis();
127 
128  auto&& shapeFunctionValues = shapeFunctionValueContainer_[node];
129  localBasis.evaluateFunction(x_, shapeFunctionValues);
130 
131  // Get range entry associated to this node
132  auto&& re = nodeToRangeEntry_(node, y_);
133 
134 
135  for (size_type i = 0; i < localBasis.size(); ++i)
136  {
137  auto&& multiIndex = localIndexSet_.index(node.localIndex(i));
138 
139  // Get coefficient associated to i-th shape function
140  auto&& c = coefficients_[multiIndex];
141 
142  // Get value of i-th shape function
143  auto&& v = shapeFunctionValues[i];
144 
145  // Notice that the range entry re, the coefficient c, and the shape functions
146  // value v may all be scalar, vector, matrix, or general container valued.
147  // The matching of their entries is done via the multistage procedure described
148  // in the class documentation of DiscreteGlobalBasisFunction.
151  assert(dimC*dimV == FlatVectorBackend<RangeBlock>::size(re));
152  for(size_type j=0; j<dimC; ++j)
153  {
155  for(size_type k=0; k<dimV; ++k)
156  {
158  FlatVectorBackend<RangeBlock>::getEntry(re, j*dimV + k) += c_j*v_k;
159  }
160  }
161  }
162  }
163 
164  const LocalDomain& x_;
165  Range& y_;
166  const LocalIndexSet& localIndexSet_;
167  const Vector& coefficients_;
168  const NodeToRangeEntry& nodeToRangeEntry_;
169  ShapeFunctionValueContainer& shapeFunctionValueContainer_;
170  };
171 
172 
173  public:
174 
179 
181  : globalFunction_(&globalFunction)
182  , localBasisView_(globalFunction.basis().localView())
183  , localIndexSet_(globalFunction.basis().localIndexSet())
184  {
185  // Here we assume that the tree can be accessed, traversed,
186  // and queried for tree indices even in unbound state.
187  subTree_ = &TypeTree::child(localBasisView_.tree(), globalFunction_->treePath());
188  shapeFunctionValueContainer_.init(*subTree_);
189 // localDoFs_.reserve(localBasisView_.maxSize());
190  }
191 
193  : globalFunction_(other.globalFunction_)
194  , localBasisView_(other.localBasisView_)
195  , localIndexSet_(globalFunction_->basis().localIndexSet())
196  , bound_(other.bound_)
197  {
198  if (other.bound_)
199  localIndexSet_.bind(localBasisView_);
200 
201  // Here we assume that the tree can be accessed, traversed,
202  // and queried for tree indices even in unbound state.
203  subTree_ = &TypeTree::child(localBasisView_.tree(), globalFunction_->treePath());
204  shapeFunctionValueContainer_.init(*subTree_);
205  }
206 
208  {
209  globalFunction_ = other.globalFunction_;
210  localBasisView_ = other.localBasisView_;
211  localIndexSet_ = other.localIndexSet_;
212  subTree_ = &TypeTree::child(localBasisView_.tree(), globalFunction_->treePath());
213 
214  // Here we assume that the tree can be accessed, traversed,
215  // and queried for tree indices even in unbound state.
216  shapeFunctionValueContainer_.init(*subTree_);
217  }
218 
225  void bind(const Element& element)
226  {
227  localBasisView_.bind(element);
228  localIndexSet_.bind(localBasisView_);
229  bound_ = true;
230 
231  // Read dofs associated to bound element
232 // localDoFs_.resize(subTree.size());
233 // for (size_type i = 0; i < subTree.size(); ++i)
234 // localDoFs_[i] = globalFunction_->dofs()[localIndexSet_.index(i)];
235  }
236 
237  void unbind()
238  {
239  localIndexSet_.unbind();
240  localBasisView_.unbind();
241  bound_ = false;
242  }
243 
247  bool bound() const {
248  return bound_;
249  }
250 
260  Range operator()(const Domain& x) const
261  {
262  auto y = Range(0);
263 
264  LocalEvaluateVisitor localEvaluateVisitor(x, y, localIndexSet_, globalFunction_->dofs(), globalFunction_->nodeToRangeEntry(), shapeFunctionValueContainer_);
265  TypeTree::applyToTree(*subTree_, localEvaluateVisitor);
266 
267  return y;
268  }
269 
270  const Element& localContext() const
271  {
272  return localBasisView_.element();
273  }
274 
276  {
277  DUNE_THROW(NotImplemented,"not implemented");
278  }
279 
280  private:
281 
282  const DiscreteGlobalBasisFunction* globalFunction_;
283  LocalBasisView localBasisView_;
284  LocalIndexSet localIndexSet_;
285 
286  mutable ShapeFunctionValueContainer shapeFunctionValueContainer_;
287 // std::vector<typename V::value_type> localDoFs_;
288  const SubTree* subTree_;
289 
290  bool bound_ = false;
291  };
292 
293  DiscreteGlobalBasisFunction(const Basis & basis, const TreePath& treePath, const V & coefficients, const NodeToRangeEntry& nodeToRangeEntry) :
294  entitySet_(basis.gridView()),
295  basis_(stackobject_to_shared_ptr(basis)),
296  treePath_(treePath),
297  coefficients_(stackobject_to_shared_ptr(coefficients)),
298  nodeToRangeEntry_(stackobject_to_shared_ptr(nodeToRangeEntry))
299  {}
300 
301  DiscreteGlobalBasisFunction(std::shared_ptr<const Basis> basis, const TreePath& treePath, std::shared_ptr<const V> coefficients, std::shared_ptr<const NodeToRangeEntry> nodeToRangeEntry) :
302  entitySet_(basis->gridView()),
303  basis_(basis),
304  treePath_(treePath),
305  coefficients_(coefficients),
306  nodeToRangeEntry_(nodeToRangeEntry)
307  {}
308 
309  const Basis& basis() const
310  {
311  return *basis_;
312  }
313 
314  const TreePath& treePath() const
315  {
316  return treePath_;
317  }
318 
319  const V& dofs() const
320  {
321  return *coefficients_;
322  }
323 
325  {
326  return *nodeToRangeEntry_;
327  }
328 
329  // TODO: Implement this using hierarchic search
330  Range operator() (const Domain& x) const
331  {
332  DUNE_THROW(NotImplemented,"not implemented");
333  }
334 
336  {
337  DUNE_THROW(NotImplemented,"not implemented");
338  }
339 
356  {
357  return LocalFunction(t);
358  }
359 
363  const EntitySet& entitySet() const
364  {
365  return entitySet_;
366  }
367 
368 private:
369 
370  EntitySet entitySet_;
371  std::shared_ptr<const Basis> basis_;
372  const TreePath treePath_;
373  std::shared_ptr<const V> coefficients_;
374  std::shared_ptr<const NodeToRangeEntry> nodeToRangeEntry_;
375 };
376 
377 
378 
389 template<typename... TT>
391 
392 
393 
394 template<typename R, typename B, typename TP, typename V>
395 auto makeDiscreteGlobalBasisFunction(B&& basis, const TP& treePath, V&& vector)
396 {
397  using Basis = std::decay_t<B>;
398  using Vector = std::decay_t<V>;
400  auto nodeToRangeEntryPtr = std::make_shared<NTREM>(makeDefaultNodeToRangeMap(basis, treePath));
401  auto basisPtr = Dune::wrap_or_move(std::forward<B>(basis));
402  auto vectorPtr = Dune::wrap_or_move(std::forward<V>(vector));
403  return DiscreteGlobalBasisFunction<Basis, TP, Vector, NTREM, R>(basisPtr, treePath, vectorPtr, nodeToRangeEntryPtr);
404 }
405 
406 
407 
408 template<typename R, typename B, typename V>
409 auto makeDiscreteGlobalBasisFunction(B&& basis, V&& vector)
410 {
411  return makeDiscreteGlobalBasisFunction<R>(std::forward<B>(basis), TypeTree::hybridTreePath(), std::forward<V>(vector));
412 }
413 
414 
415 
416 } // namespace Functions
417 } // namespace Dune
418 
419 #endif // DUNE_FUNCTIONS_GRIDFUNCTIONS_DISCRETEGLOBALBASISFUNCTIONS_HH
Imp::GridFunctionTraits< Range(Domain), EntitySet, DefaultDerivativeTraits, 16 > Traits
Definition: discreteglobalbasisfunction.hh:88
friend Traits::LocalFunctionTraits::DerivativeInterface derivative(const LocalFunction &t)
Definition: discreteglobalbasisfunction.hh:275
LocalDomain Domain
Definition: discreteglobalbasisfunction.hh:176
TP TreePath
Definition: discreteglobalbasisfunction.hh:73
GridView::template Codim< codim >::Entity Element
Type of Elements contained in this EntitySet.
Definition: gridviewentityset.hh:32
bool bound() const
Check if LocalFunction is already bound to an element.
Definition: discreteglobalbasisfunction.hh:247
typename Basis::GridView GridView
Definition: discreteglobalbasisfunction.hh:76
void localFunction(DiscreteGlobalBasisFunction< TT... > &&t)=delete
Construction of local functions from a temporary DiscreteGlobalBasisFunction (forbidden) ...
const Element & localContext() const
Definition: discreteglobalbasisfunction.hh:270
GlobalFunction::Element Element
Definition: discreteglobalbasisfunction.hh:178
typename EntitySet::GlobalCoordinate Domain
Definition: discreteglobalbasisfunction.hh:82
static auto size(VV &&v) -> decltype(v.size())
Definition: flatvectorbackend.hh:41
A simple node to range map using lexicographic ordering.
Definition: defaultnodetorangemap.hh:38
typename EntitySet::Element Element
Definition: discreteglobalbasisfunction.hh:86
Definition: flatvectorbackend.hh:20
const Basis & basis() const
Definition: discreteglobalbasisfunction.hh:309
typename TypeTree::ChildForTreePath< Tree, TreePath > SubTree
Definition: discreteglobalbasisfunction.hh:79
Definition: discreteglobalbasisfunction.hh:90
NTRE NodeToRangeEntry
Definition: discreteglobalbasisfunction.hh:80
DiscreteGlobalBasisFunction(const Basis &basis, const TreePath &treePath, const V &coefficients, const NodeToRangeEntry &nodeToRangeEntry)
Definition: discreteglobalbasisfunction.hh:293
static auto getEntry(VV &&v, const Index &i) -> decltype(v[i])
Definition: flatvectorbackend.hh:25
friend LocalFunction localFunction(const DiscreteGlobalBasisFunction &t)
Construct local function from a DiscreteGlobalBasisFunction.
Definition: discreteglobalbasisfunction.hh:355
typename Basis::LocalView::Tree Tree
Definition: discreteglobalbasisfunction.hh:78
Element::Geometry::LocalCoordinate LocalCoordinate
Type of local coordinates with respect to the Element.
Definition: gridviewentityset.hh:35
Definition: gridfunction.hh:31
V Vector
Definition: discreteglobalbasisfunction.hh:74
const EntitySet & entitySet() const
Get associated EntitySet.
Definition: discreteglobalbasisfunction.hh:363
Element::Geometry::GlobalCoordinate GlobalCoordinate
Definition: gridviewentityset.hh:36
DefaultNodeToRangeMap< Tree > makeDefaultNodeToRangeMap(const Tree &tree)
Definition: defaultnodetorangemap.hh:106
B Basis
Definition: discreteglobalbasisfunction.hh:72
GlobalFunction::Range Range
Definition: discreteglobalbasisfunction.hh:177
const NodeToRangeEntry & nodeToRangeEntry() const
Definition: discreteglobalbasisfunction.hh:324
void unbind()
Definition: discreteglobalbasisfunction.hh:237
LocalFunction operator=(const LocalFunction &other)
Definition: discreteglobalbasisfunction.hh:207
const V & dofs() const
Definition: discreteglobalbasisfunction.hh:319
Range operator()(const Domain &x) const
Evaluate LocalFunction at bound element.
Definition: discreteglobalbasisfunction.hh:260
Definition: polynomial.hh:7
typename EntitySet::LocalCoordinate LocalDomain
Definition: discreteglobalbasisfunction.hh:85
LocalFunction(const LocalFunction &other)
Definition: discreteglobalbasisfunction.hh:192
friend Traits::DerivativeInterface derivative(const DiscreteGlobalBasisFunction &t)
Definition: discreteglobalbasisfunction.hh:335
void bind(const Element &element)
Bind LocalFunction to grid element.
Definition: discreteglobalbasisfunction.hh:225
const TreePath & treePath() const
Definition: discreteglobalbasisfunction.hh:314
auto makeDiscreteGlobalBasisFunction(B &&basis, const TP &treePath, V &&vector)
Definition: discreteglobalbasisfunction.hh:395
R Range
Definition: discreteglobalbasisfunction.hh:83
DiscreteGlobalBasisFunction(std::shared_ptr< const Basis > basis, const TreePath &treePath, std::shared_ptr< const V > coefficients, std::shared_ptr< const NodeToRangeEntry > nodeToRangeEntry)
Definition: discreteglobalbasisfunction.hh:301
A grid function induced by a global basis and a coefficient vector.
Definition: discreteglobalbasisfunction.hh:69
LocalFunction(const DiscreteGlobalBasisFunction &globalFunction)
Definition: discreteglobalbasisfunction.hh:180