Dune-Fufem 2.11-git
Loading...
Searching...
No Matches
unaryoperators.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
4// SPDX-FileCopyrightText: Copyright © DUNE-FUFEM Project contributors, see file AUTHORS.md
5// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
6
7#ifndef DUNE_FUFEM_FORMS_UNARYOPERATORS_HH
8#define DUNE_FUFEM_FORMS_UNARYOPERATORS_HH
9
10#include <cstddef>
11#include <type_traits>
12#include <vector>
13
21
22#if DUNE_VERSION_GTE(DUNE_FUNCTIONS, 2, 11)
25#else
26#include <dune/typetree/childextraction.hh>
27#include <dune/typetree/treepath.hh>
28#endif
29
31
33
37
39
40
41
42namespace Dune::Fufem::Forms {
43
44
45
59 template<class B, class TP, std::size_t argIndex>
60 class FEOperatorBase : public UnaryOperator<argIndex>
61 {
62
63 protected:
64 using LocalView = typename B::LocalView;
65 using Tree = typename LocalView::Tree;
68
69 // Helper function to derive the leafTreePath associated
70 // to a treePath. For treePaths referring to a leaf this is
71 // the identity. For treePaths referring to the a power
72 // node whose children are leaf, it's the first child.
73 // This is used to implement vector valued ansatz functions
74 // for power nodes.
75 static auto leafTreePath(const TP& tp)
76 {
77 if constexpr(Dune::Fufem::Impl::Concept::LeafTreeNode<Node>)
78 return tp;
79 else if constexpr(Dune::Fufem::Impl::Concept::UniformInnerTreeNode<Node>
80 and Dune::Fufem::Impl::Concept::LeafTreeNode<Dune::TypeTree::Child<Node, 0>>)
81 return Dune::TypeTree::push_back(tp, Dune::Indices::_0);
82 }
83
86 using Basis = B;
87 using TreePath = TP;
88
89 public:
90
91 using Element = typename Basis::LocalView::Element;
92 using Intersection = typename Basis::GridView::Intersection;
93
98
100 {
101 protected:
102
105
106 public:
107
111
112 LocalOperator(const SubspaceBasis& subspaceBasis, bool isAffine) :
113 subspaceBasis_(subspaceBasis),
115 leafNode_(nullptr),
116 localView_(nullptr),
118 cacheIndex_(std::numeric_limits<std::size_t>::max()),
120 {}
121
125
126 void unbind()
127 {}
128
129 auto quadratureRuleKey() const
130 {
131 return quadratureRuleKey_;
132 }
133
134 template<class... LV>
135 void registerLocalViews(const LV&... lvs)
136 {
137 Impl::visitMatchingLocalView([&](const auto& localView) {
138 localView_ = &localView;
139 leafNode_ = & Dune::TypeTree::child(localView.tree(), leafTreePath_);
140 }, subspaceBasis_.rootBasis(), lvs...);
141 }
142
143 template<class... LV>
144 void registerOutsideLocalViews(const LV&... lvs)
145 {}
146
147 void registerCaches(CacheManager& cacheManager)
148 {
149 const auto& tree = localView_->tree();
150 cacheIndex_ = cacheManager.registerCache(UniqueCacheId(tree), TreeCache(tree));
151 if (not isAffine_)
152 cacheManager.template getCache<TreeCache>(cacheIndex_)[subspaceBasis_.prefixPath()].setNonAffine();
153 }
154
156 {}
157
158 protected:
159
160 const LeafNode& leafNode() const
161 {
162 return *leafNode_;
163 }
164
165 auto& leafNodeCache(CacheManager& cacheManager)
166 {
167 return cacheManager.template getCache<TreeCache>(cacheIndex_)[leafTreePath_];
168 }
169
177 };
178
179 auto basis() const
180 {
181 return std::tie(subspaceBasis_.rootBasis());
182 }
183
184 auto treePath() const
185 {
186 return std::tie(subspaceBasis_.prefixPath());
187 }
188
189 bool isAffine() const
190 {
191 return isAffine_;
192 }
193
194 protected:
197 };
198
199
200
210 template<class B, class TP, std::size_t argIndex>
211 class FEFunctionOperator : public FEOperatorBase<B, TP, argIndex>
212 {
214 using Node = typename Base::Node;
215 using LeafLBTraits = typename Base::LeafNode::FiniteElement::Traits::LocalBasisType::Traits;
216
217 public:
218
219 using Element = typename Base::Element;
221 Dune::Fufem::Impl::Concept::LeafTreeNode<Node>,
222 typename LeafLBTraits::RangeType,
223 Dune::FieldVector<typename LeafLBTraits::RangeFieldType, Node::degree()>>;
224
225 using Base::Base;
226
228 {
229 using Base::LocalOperator::quadratureRuleKey_;
230 using Base::LocalOperator::leafNode;
231 using Base::LocalOperator::leafNodeCache;
233
234 public:
235
237 using CacheManager = typename Base::LocalOperator::CacheManager;
239
240 void bind(const Element&)
241 {
242 if (leafNode().size()!=0)
243 quadratureRuleKey_ = QuadratureRuleKey(leafNode().finiteElement());
244 else
245 quadratureRuleKey_ = QuadratureRuleKey(this->localView_->element().type(), 0);
246 }
247
248 void bind(const Intersection& intersection, const Element& element, const Element& otherElement)
249 {
250 bind(element);
251 }
252
253 template<class... OutsideCacheManager>
254 void bindToCaches(CacheManager& cacheManager, OutsideCacheManager&... outsideCacheManager)
255 {
256 valueCache_ = &(leafNodeCache(cacheManager).getValues());
257 }
258
260 {
261 using namespace Impl::Tensor;
262 using namespace Dune::Indices;
263 const auto& values = (*valueCache_)[index];
264 std::size_t size = leafNode().size();
265 std::size_t indexOffset = (size==0) ? 0 : leafNode().localIndex(0);
266 if constexpr(Dune::Fufem::Impl::Concept::LeafTreeNode<Node>)
267 return SparseTensor(_2,
268 [&, size, indexOffset](auto&& f) {
269 for(std::size_t i=0; i<size; ++i)
270 f(values[i], _0, indexOffset+i);
271 },
272 size,
274 );
275 else if constexpr(Dune::Fufem::Impl::Concept::UniformInnerTreeNode<Node>
276 and Dune::Fufem::Impl::Concept::LeafTreeNode<Dune::TypeTree::Child<Node, 0>>)
277 return SparseTensor(_2,
278 [&, size, indexOffset](auto&& f) {
279 for(std::size_t j=0; j<Node::degree(); ++j)
280 for(std::size_t i=0; i<size; ++i)
281 {
282 auto result = Range(0);
283 result[j] = values[i];
284 f(result, _0, indexOffset + j*size + i);
285 }
286 },
287 Node::degree() * size,
289 );
290 }
291
292 private:
293 const typename Base::LocalOperator::LeafNodeCache::ValueCache* valueCache_ = nullptr;
294 };
295
297 {
298 return LocalOperator(op);
299 }
300
301 template<std::size_t i>
303 {
304 using Basis = typename Base::Basis;
305 auto childTP = Dune::TypeTree::push_back(Base::subspaceBasis_.prefixPath(), childIndex);
307 }
308
309 };
310
311
312
313
323 template<class B, class TP, std::size_t argIndex>
324 class FEFunctionJacobianOperator : public FEOperatorBase<B, TP, argIndex>
325 {
327 using Node = typename Base::Node;
328 using LeafLBTraits = typename Base::LeafNode::FiniteElement::Traits::LocalBasisType::Traits;
329
331 Dune::Fufem::Impl::Concept::LeafTreeNode<Node>,
332 typename LeafLBTraits::JacobianType,
333 Dune::FieldMatrix<typename LeafLBTraits::RangeFieldType, Node::degree(), LeafLBTraits::dimDomain>>;
334
335 using GeometryJacobianInverse = typename Node::Element::Geometry::JacobianInverse;
336
337 public:
338
339 using Element = typename Base::Element;
340 using Range = typename Impl::GlobalJacobianTraits<ReferenceJacobian, GeometryJacobianInverse>::type;
341
342 using Base::Base;
343
345 {
346 using Base::LocalOperator::quadratureRuleKey_;
347 using Base::LocalOperator::leafNode;
348 using Base::LocalOperator::leafNodeCache;
350
351 public:
352
354 using CacheManager = typename Base::LocalOperator::CacheManager;
356
357 void bind(const Element&)
358 {
359 if (leafNode().size()!=0)
361 else
362 quadratureRuleKey_ = QuadratureRuleKey(this->localView_->element().type(), 0);
363 }
364
365 void bind(const Intersection& intersection, const Element& element, const Element& otherElement)
366 {
367 bind(element);
368 }
369
370 template<class... OutsideCacheManager>
371 void bindToCaches(CacheManager& cacheManager, OutsideCacheManager&... outsideCacheManager)
372 {
373 globalJacobianCache_ = &(leafNodeCache(cacheManager).getGlobalJacobians());
374 }
375
377 {
378 using namespace Impl::Tensor;
379 using namespace Dune::Indices;
380 const auto& globalJacobians = (*globalJacobianCache_)[index];
381 std::size_t size = leafNode().size();
382 std::size_t indexOffset = (size==0) ? 0 : leafNode().localIndex(0);
383 if constexpr(Dune::Fufem::Impl::Concept::LeafTreeNode<Node>)
384 return SparseTensor(_2,
385 [&, size, indexOffset](auto&& f) {
386 for(std::size_t i=0; i<size; ++i)
387 f(globalJacobians[i], _0, indexOffset+i);
388 },
389 size,
391 );
392 else if constexpr(Dune::Fufem::Impl::Concept::UniformInnerTreeNode<Node>
393 and Dune::Fufem::Impl::Concept::LeafTreeNode<Dune::TypeTree::Child<Node, 0>>)
394 return SparseTensor(_2,
395 [&, size, indexOffset](auto&& f) {
396 for(std::size_t j=0; j<Node::degree(); ++j)
397 for(std::size_t i=0; i<size; ++i)
398 {
399 auto result = Range(0);
400 result[j] = globalJacobians[i][0];
401 f(result, _0, indexOffset + j*size + i);
402 }
403 },
404 Node::degree() * size,
406 );
407 }
408
409 private:
410 const typename Base::LocalOperator::LeafNodeCache::GlobalJacobianCache* globalJacobianCache_ = nullptr;
411 };
412
414 {
415 return LocalOperator(op);
416 }
417
418 template<std::size_t i>
420 {
421 using Basis = typename Base::Basis;
422 auto childTP = Dune::TypeTree::push_back(Base::subspaceBasis_.prefixPath(), childIndex);
424 }
425
426 };
427
428
429
439 template<class B, class TP, std::size_t argIndex>
440 class FEFunctionDivergenceOperator : public FEOperatorBase<B, TP, argIndex>
441 {
443 using Node = typename Base::Node;
444 using LeafLBTraits = typename Base::LeafNode::FiniteElement::Traits::LocalBasisType::Traits;
445
446 public:
447
448 using Element = typename Base::Element;
450 Dune::Fufem::Impl::Concept::LeafTreeNode<Node>,
451 typename LeafLBTraits::RangeFieldType,
452 typename LeafLBTraits::JacobianType::block_type>;
453
454 using Base::Base;
455
457 {
458 using Base::LocalOperator::quadratureRuleKey_;
459 using Base::LocalOperator::leafNode;
460 using Base::LocalOperator::leafNodeCache;
462
463 public:
464
466 using CacheManager = typename Base::LocalOperator::CacheManager;
468
469 void bind(const Element&)
470 {
471 if (leafNode().size()!=0)
473 else
474 quadratureRuleKey_ = QuadratureRuleKey(this->localView_->element().type(), 0);
475 }
476
477 void bind(const Intersection& intersection, const Element& element, const Element& otherElement)
478 {
479 bind(element);
480 }
481
482 template<class... OutsideCacheManager>
483 void bindToCaches(CacheManager& cacheManager, OutsideCacheManager&... outsideCacheManager)
484 {
485 globalJacobianCache_ = &(leafNodeCache(cacheManager).getGlobalJacobians());
486 }
487
489 {
490 using namespace Impl::Tensor;
491 using namespace Dune::Indices;
492 using LocalBasisTraits = typename Base::LeafNode::FiniteElement::Traits::LocalBasisType::Traits;
493 using Field = typename LocalBasisTraits::RangeFieldType;
494 const auto& globalJacobians = (*globalJacobianCache_)[index];
495 std::size_t size = leafNode().size();
496 std::size_t indexOffset = (size==0) ? 0 : leafNode().localIndex(0);
497 if constexpr(Dune::Fufem::Impl::Concept::LeafTreeNode<Node>)
498 return SparseTensor(_2,
499 [&, size, indexOffset](auto&& f) {
500 for(std::size_t i=0; i<size; ++i)
501 {
502 auto div = Field{0};
503 for(std::size_t j=0; j<globalJacobians[i].N(); ++j)
504 div += globalJacobians[i][j][j];
505 f(div, _0, indexOffset+i);
506 }
507 },
508 size,
510 );
511 else if constexpr(Dune::Fufem::Impl::Concept::UniformInnerTreeNode<Node>
512 and Dune::Fufem::Impl::Concept::LeafTreeNode<Dune::TypeTree::Child<Node, 0>>)
513 return SparseTensor(_2,
514 [&, size, indexOffset](auto&& f) {
515 // Here we should compute the trace of the global Jacobian J
516 // that we would need to build first. But since only the
517 // j-th row of J is nonzero, we can simply
518 // return the diagonal entry of this row which coincides
519 // with the j-th entry of the gradient of
520 // the respective scalar basis function.
521 for(std::size_t j=0; j<Node::degree(); ++j)
522 for(std::size_t i=0; i<size; ++i)
523 f(globalJacobians[i][0][j], _0, indexOffset + j*size + i);
524 },
525 Node::degree() * size,
527 );
528 }
529
530 private:
531 const typename Base::LocalOperator::LeafNodeCache::GlobalJacobianCache* globalJacobianCache_ = nullptr;
532 };
533
535 {
536 return LocalOperator(op);
537 }
538
539 };
540
541
542
543} // namespace Dune::Fufem::Forms
544
545
546
547#endif // DUNE_FUFEM_FORMS_UNARYOPERATORS_HH
This header provides fallback implementations for dune-typetree<2.11.
int size() const
std::ptrdiff_t index() const
size_t() const
decltype(auto) child(Node &&node, TreePath< Indices... > treePath)
constexpr index_constant< 0 > _0
auto div(const Op &op)
Obtain the divergence of an operator.
Definition userfunctions.hh:1200
STL namespace.
Definition baseclass.hh:22
Base class for unary multilinear operator implementations.
Definition baseclass.hh:91
A hierarchic cache for storing shape function evaluations for a tree.
Definition shapefunctioncache.hh:107
Objects of this class are used to uniquely identifies a cache.
Definition shapefunctioncache.hh:569
A class for managing caches of different types.
Definition shapefunctioncache.hh:615
size_type registerCache(UniqueCacheId uniqueCacheId, Cache &&cache)
Register a new cache.
Definition shapefunctioncache.hh:753
Base class of elementary differential operators on an FE-space.
Definition unaryoperators.hh:61
typename Dune::TypeTree::ChildForTreePath< Tree, TP > Node
Definition unaryoperators.hh:66
typename B::LocalView LocalView
Definition unaryoperators.hh:64
SubspaceBasis subspaceBasis_
Definition unaryoperators.hh:195
typename Dune::TypeTree::ChildForTreePath< Tree, LeafTreePath > LeafNode
Definition unaryoperators.hh:85
B Basis
Definition unaryoperators.hh:86
typename Basis::LocalView::Element Element
Definition unaryoperators.hh:91
bool isAffine_
Definition unaryoperators.hh:196
decltype(leafTreePath(std::declval< TP >())) LeafTreePath
Definition unaryoperators.hh:84
FEOperatorBase(const Basis &basis, const TreePath &treePath, bool isAffine=true)
Definition unaryoperators.hh:94
typename Dune::Functions::SubspaceBasis< B, TP > SubspaceBasis
Definition unaryoperators.hh:67
TP TreePath
Definition unaryoperators.hh:87
static auto leafTreePath(const TP &tp)
Definition unaryoperators.hh:75
typename Basis::GridView::Intersection Intersection
Definition unaryoperators.hh:92
typename LocalView::Tree Tree
Definition unaryoperators.hh:65
auto basis() const
Definition unaryoperators.hh:179
auto treePath() const
Definition unaryoperators.hh:184
bool isAffine() const
Definition unaryoperators.hh:189
bool isAffine_
Definition unaryoperators.hh:176
SubspaceBasis subspaceBasis_
Definition unaryoperators.hh:170
void unbind()
Definition unaryoperators.hh:126
LocalOperator(const SubspaceBasis &subspaceBasis, bool isAffine)
Definition unaryoperators.hh:112
void registerOutsideCaches(CacheManager &cacheManager)
Definition unaryoperators.hh:155
LocalOperator(const FEOperatorBase &op)
Definition unaryoperators.hh:122
const LocalView * localView_
Definition unaryoperators.hh:173
typename FEOperatorBase::Element Element
Definition unaryoperators.hh:108
void registerOutsideLocalViews(const LV &... lvs)
Definition unaryoperators.hh:144
void registerCaches(CacheManager &cacheManager)
Definition unaryoperators.hh:147
auto quadratureRuleKey() const
Definition unaryoperators.hh:129
ShapeFunctionCache< Tree > TreeCache
Definition unaryoperators.hh:103
QuadratureRuleKey quadratureRuleKey_
Definition unaryoperators.hh:174
auto & leafNodeCache(CacheManager &cacheManager)
Definition unaryoperators.hh:165
std::size_t cacheIndex_
Definition unaryoperators.hh:175
void registerLocalViews(const LV &... lvs)
Definition unaryoperators.hh:135
const LeafNode * leafNode_
Definition unaryoperators.hh:172
const LeafTreePath leafTreePath_
Definition unaryoperators.hh:171
const LeafNode & leafNode() const
Definition unaryoperators.hh:160
typename FEOperatorBase::Intersection Intersection
Definition unaryoperators.hh:109
Linear map representing the elements of an FE-space.
Definition unaryoperators.hh:212
auto childOperator(Dune::index_constant< i > childIndex) const
Definition unaryoperators.hh:302
typename Base::Element Element
Definition unaryoperators.hh:219
friend LocalOperator localOperator(const FEFunctionOperator &op)
Definition unaryoperators.hh:296
std::conditional_t< Dune::Fufem::Impl::Concept::LeafTreeNode< Node >, typename LeafLBTraits::RangeType, Dune::FieldVector< typename LeafLBTraits::RangeFieldType, Node::degree()> > Range
Definition unaryoperators.hh:223
typename Base::LocalOperator::Intersection Intersection
Definition unaryoperators.hh:236
void bind(const Element &)
Definition unaryoperators.hh:240
void bind(const Intersection &intersection, const Element &element, const Element &otherElement)
Definition unaryoperators.hh:248
typename Base::LocalOperator::CacheManager CacheManager
Definition unaryoperators.hh:237
void bindToCaches(CacheManager &cacheManager, OutsideCacheManager &... outsideCacheManager)
Definition unaryoperators.hh:254
auto operator()(std::size_t index) const
Definition unaryoperators.hh:259
typename FEFunctionOperator::Range Range
Definition unaryoperators.hh:238
Linear map representing the jacobians of the elements of an FE-space.
Definition unaryoperators.hh:325
typename Impl::GlobalJacobianTraits< ReferenceJacobian, GeometryJacobianInverse >::type Range
Definition unaryoperators.hh:340
friend LocalOperator localOperator(const FEFunctionJacobianOperator &op)
Definition unaryoperators.hh:413
auto childOperator(Dune::index_constant< i > childIndex) const
Definition unaryoperators.hh:419
typename Base::Element Element
Definition unaryoperators.hh:339
void bind(const Element &)
Definition unaryoperators.hh:357
void bind(const Intersection &intersection, const Element &element, const Element &otherElement)
Definition unaryoperators.hh:365
typename Base::LocalOperator::Intersection Intersection
Definition unaryoperators.hh:353
typename Base::LocalOperator::CacheManager CacheManager
Definition unaryoperators.hh:354
void bindToCaches(CacheManager &cacheManager, OutsideCacheManager &... outsideCacheManager)
Definition unaryoperators.hh:371
auto operator()(std::size_t index) const
Definition unaryoperators.hh:376
typename FEFunctionJacobianOperator::Range Range
Definition unaryoperators.hh:355
Linear map representing the divergenc of the elements of an FE-space.
Definition unaryoperators.hh:441
typename Base::Element Element
Definition unaryoperators.hh:448
friend LocalOperator localOperator(const FEFunctionDivergenceOperator &op)
Definition unaryoperators.hh:534
std::conditional_t< Dune::Fufem::Impl::Concept::LeafTreeNode< Node >, typename LeafLBTraits::RangeFieldType, typename LeafLBTraits::JacobianType::block_type > Range
Definition unaryoperators.hh:452
void bindToCaches(CacheManager &cacheManager, OutsideCacheManager &... outsideCacheManager)
Definition unaryoperators.hh:483
void bind(const Element &)
Definition unaryoperators.hh:469
void bind(const Intersection &intersection, const Element &element, const Element &otherElement)
Definition unaryoperators.hh:477
typename Base::LocalOperator::Intersection Intersection
Definition unaryoperators.hh:465
typename Base::LocalOperator::CacheManager CacheManager
Definition unaryoperators.hh:466
typename FEFunctionDivergenceOperator::Range Range
Definition unaryoperators.hh:467
auto operator()(std::size_t index) const
Definition unaryoperators.hh:488
A token that specifies a quadrature rule.
Definition quadraturerulecache.hh:39
QuadratureRuleKey derivative() const
Definition quadraturerulecache.hh:154
T forward(T... args)
T tie(T... args)