Dune-Fufem 2.11
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
28#endif
29
31
33
37
40
41
42
43namespace Dune::Fufem::Forms {
44
45
46
60 template<class B, class TP, std::size_t argIndex>
61 class FEOperatorBase : public UnaryOperator<argIndex>
62 {
63
64 protected:
65 using LocalView = typename B::LocalView;
66 using Tree = typename LocalView::Tree;
69
70 // Helper function to derive the leafTreePath associated
71 // to a treePath. For treePaths referring to a leaf this is
72 // the identity. For treePaths referring to the a power
73 // node whose children are leaf, it's the first child.
74 // This is used to implement vector valued ansatz functions
75 // for power nodes.
76 static auto leafTreePath(const TP& tp)
77 {
78 if constexpr(Dune::Fufem::Impl::Concept::LeafTreeNode<Node>)
79 return tp;
80 else if constexpr(Dune::Fufem::Impl::Concept::UniformInnerTreeNode<Node>
81 and Dune::Fufem::Impl::Concept::LeafTreeNode<Dune::TypeTree::Child<Node, 0>>)
82 return Dune::TypeTree::push_back(tp, Dune::Indices::_0);
83 }
84
87 using Basis = B;
88 using TreePath = TP;
89
90 public:
91
92 using Element = typename Basis::LocalView::Element;
93 using Intersection = typename Basis::GridView::Intersection;
94
95 FEOperatorBase(const Basis& basis, const TreePath& treePath, bool isAffine = true) :
98 {}
99
101 {
102 protected:
103
106
107 public:
108
112
113 LocalOperator(const SubspaceBasis& subspaceBasis, bool isAffine) :
114 subspaceBasis_(subspaceBasis),
116 leafNode_(nullptr),
117 localView_(nullptr),
119 cacheIndex_(std::numeric_limits<std::size_t>::max()),
121 {}
122
125 {}
126
127 void unbind()
128 {}
129
130 auto quadratureRuleKey() const
131 {
132 return quadratureRuleKey_;
133 }
134
135 template<class... LV>
136 void registerLocalViews(const LV&... lvs)
137 {
138 Impl::visitMatchingLocalView([&](const auto& localView) {
139 localView_ = &localView;
140 leafNode_ = & Dune::TypeTree::child(localView.tree(), leafTreePath_);
141 }, subspaceBasis_.rootBasis(), lvs...);
142 }
143
144 template<class... LV>
145 void registerOutsideLocalViews(const LV&... lvs)
146 {}
147
148 void registerCaches(CacheManager& cacheManager)
149 {
150 const auto& tree = localView_->tree();
151 cacheIndex_ = cacheManager.registerCache(UniqueCacheId(tree), TreeCache(tree));
152 if (not isAffine_)
153 cacheManager.template getCache<TreeCache>(cacheIndex_)[subspaceBasis_.prefixPath()].setNonAffine();
154 }
155
157 {}
158
159 protected:
160
161 const LeafNode& leafNode() const
162 {
163 return *leafNode_;
164 }
165
166 auto& leafNodeCache(CacheManager& cacheManager)
167 {
168 return cacheManager.template getCache<TreeCache>(cacheIndex_)[leafTreePath_];
169 }
170
178 };
179
180 auto basis() const
181 {
182 return std::tie(subspaceBasis_.rootBasis());
183 }
184
185 auto treePath() const
186 {
187 return std::tie(subspaceBasis_.prefixPath());
188 }
189
190 bool isAffine() const
191 {
192 return isAffine_;
193 }
194
199 template<std::size_t k>
201 {
203 }
204
205 protected:
208 };
209
210
211
221 template<class B, class TP, std::size_t argIndex>
222 class FEFunctionOperator : public FEOperatorBase<B, TP, argIndex>
223 {
225 using Node = typename Base::Node;
226 using LeafLBTraits = typename Base::LeafNode::FiniteElement::Traits::LocalBasisType::Traits;
227
228 public:
229
230 using Element = typename Base::Element;
232 Dune::Fufem::Impl::Concept::LeafTreeNode<Node>,
233 typename LeafLBTraits::RangeType,
234 Dune::FieldVector<typename LeafLBTraits::RangeFieldType, Node::degree()>>;
235
236 using Base::Base;
237
239 : Base(other)
240 {}
241
243 {
244 using Base::LocalOperator::quadratureRuleKey_;
245 using Base::LocalOperator::leafNode;
246 using Base::LocalOperator::leafNodeCache;
248
249 public:
250
252 using CacheManager = typename Base::LocalOperator::CacheManager;
254
255 void bind(const Element&)
256 {
257 if (leafNode().size()!=0)
258 quadratureRuleKey_ = QuadratureRuleKey(leafNode().finiteElement());
259 else
260 quadratureRuleKey_ = QuadratureRuleKey(this->localView_->element().type(), 0);
261 }
262
263 void bind(const Intersection& intersection, const Element& element, const Element& otherElement)
264 {
265 bind(element);
266 }
267
268 template<class... OutsideCacheManager>
269 void bindToCaches(CacheManager& cacheManager, OutsideCacheManager&... outsideCacheManager)
270 {
271 valueCache_ = &(leafNodeCache(cacheManager).getValues());
272 }
273
275 {
276 using namespace Impl::Tensor;
277 using namespace Dune::Indices;
278 const auto& values = (*valueCache_)[index];
279 std::size_t size = leafNode().size();
280 std::size_t indexOffset = (size==0) ? 0 : leafNode().localIndex(0);
281 if constexpr(Dune::Fufem::Impl::Concept::LeafTreeNode<Node>)
282 return SparseTensor(_2,
283 [&, size, indexOffset](auto&& f) {
284 for(std::size_t i=0; i<size; ++i)
285 f(values[i], _0, indexOffset+i);
286 },
287 size,
289 );
290 else if constexpr(Dune::Fufem::Impl::Concept::UniformInnerTreeNode<Node>
291 and Dune::Fufem::Impl::Concept::LeafTreeNode<Dune::TypeTree::Child<Node, 0>>)
292 return SparseTensor(_2,
293 [&, size, indexOffset](auto&& f) {
294 for(std::size_t j=0; j<Node::degree(); ++j)
295 for(std::size_t i=0; i<size; ++i)
296 {
297 auto result = Range(0);
298 result[j] = Dune::Fufem::asNumber(values[i]);
299 f(result, _0, indexOffset + j*size + i);
300 }
301 },
302 Node::degree() * size,
304 );
305 }
306
307 private:
308 const typename Base::LocalOperator::LeafNodeCache::ValueCache* valueCache_ = nullptr;
309 };
310
312 {
313 return LocalOperator(op);
314 }
315
316 template<std::size_t i>
318 {
319 using Basis = typename Base::Basis;
320 auto childTP = Dune::TypeTree::push_back(Base::subspaceBasis_.prefixPath(), childIndex);
322 }
323
325 template<std::size_t k>
327 {
328 return {Base::template rebindArgIndex<k>()};
329 }
330
331 };
332
333
334
335
345 template<class B, class TP, std::size_t argIndex>
346 class FEFunctionJacobianOperator : public FEOperatorBase<B, TP, argIndex>
347 {
349 using Node = typename Base::Node;
350 using LeafLBTraits = typename Base::LeafNode::FiniteElement::Traits::LocalBasisType::Traits;
351
353 Dune::Fufem::Impl::Concept::LeafTreeNode<Node>,
354 typename LeafLBTraits::JacobianType,
355 Dune::FieldMatrix<typename LeafLBTraits::RangeFieldType, Node::degree(), LeafLBTraits::dimDomain>>;
356
357 using GeometryJacobianInverse = typename Node::Element::Geometry::JacobianInverse;
358
359 public:
360
361 using Element = typename Base::Element;
362 using Range = typename Impl::GlobalJacobianTraits<ReferenceJacobian, GeometryJacobianInverse>::type;
363
364 using Base::Base;
365
367 : Base(other)
368 {}
369
371 {
372 using Base::LocalOperator::quadratureRuleKey_;
373 using Base::LocalOperator::leafNode;
374 using Base::LocalOperator::leafNodeCache;
376
377 public:
378
380 using CacheManager = typename Base::LocalOperator::CacheManager;
382
383 void bind(const Element&)
384 {
385 if (leafNode().size()!=0)
387 else
388 quadratureRuleKey_ = QuadratureRuleKey(this->localView_->element().type(), 0);
389 }
390
391 void bind(const Intersection& intersection, const Element& element, const Element& otherElement)
392 {
393 bind(element);
394 }
395
396 template<class... OutsideCacheManager>
397 void bindToCaches(CacheManager& cacheManager, OutsideCacheManager&... outsideCacheManager)
398 {
399 globalJacobianCache_ = &(leafNodeCache(cacheManager).getGlobalJacobians());
400 }
401
403 {
404 using namespace Impl::Tensor;
405 using namespace Dune::Indices;
406 const auto& globalJacobians = (*globalJacobianCache_)[index];
407 std::size_t size = leafNode().size();
408 std::size_t indexOffset = (size==0) ? 0 : leafNode().localIndex(0);
409 if constexpr(Dune::Fufem::Impl::Concept::LeafTreeNode<Node>)
410 return SparseTensor(_2,
411 [&, size, indexOffset](auto&& f) {
412 for(std::size_t i=0; i<size; ++i)
413 f(globalJacobians[i], _0, indexOffset+i);
414 },
415 size,
417 );
418 else if constexpr(Dune::Fufem::Impl::Concept::UniformInnerTreeNode<Node>
419 and Dune::Fufem::Impl::Concept::LeafTreeNode<Dune::TypeTree::Child<Node, 0>>)
420 return SparseTensor(_2,
421 [&, size, indexOffset](auto&& f) {
422 for(std::size_t j=0; j<Node::degree(); ++j)
423 for(std::size_t i=0; i<size; ++i)
424 {
425 auto result = Range(0);
426 result[j] = globalJacobians[i][0];
427 f(result, _0, indexOffset + j*size + i);
428 }
429 },
430 Node::degree() * size,
432 );
433 }
434
435 private:
436 const typename Base::LocalOperator::LeafNodeCache::GlobalJacobianCache* globalJacobianCache_ = nullptr;
437 };
438
440 {
441 return LocalOperator(op);
442 }
443
444 template<std::size_t i>
446 {
447 using Basis = typename Base::Basis;
448 auto childTP = Dune::TypeTree::push_back(Base::subspaceBasis_.prefixPath(), childIndex);
450 }
451
453 template<std::size_t k>
455 {
456 return {Base::template rebindArgIndex<k>()};
457 }
458
459 };
460
461
462
472 template<class B, class TP, std::size_t argIndex>
473 class FEFunctionDivergenceOperator : public FEOperatorBase<B, TP, argIndex>
474 {
476 using Node = typename Base::Node;
477 using LeafLBTraits = typename Base::LeafNode::FiniteElement::Traits::LocalBasisType::Traits;
478
479 public:
480
481 using Element = typename Base::Element;
483 Dune::Fufem::Impl::Concept::LeafTreeNode<Node>,
484 typename LeafLBTraits::RangeFieldType,
485 typename LeafLBTraits::JacobianType::block_type>;
486
487 using Base::Base;
488
490 : Base(other)
491 {}
492
494 {
495 using Base::LocalOperator::quadratureRuleKey_;
496 using Base::LocalOperator::leafNode;
497 using Base::LocalOperator::leafNodeCache;
499
500 public:
501
503 using CacheManager = typename Base::LocalOperator::CacheManager;
505
506 void bind(const Element&)
507 {
508 if (leafNode().size()!=0)
510 else
511 quadratureRuleKey_ = QuadratureRuleKey(this->localView_->element().type(), 0);
512 }
513
514 void bind(const Intersection& intersection, const Element& element, const Element& otherElement)
515 {
516 bind(element);
517 }
518
519 template<class... OutsideCacheManager>
520 void bindToCaches(CacheManager& cacheManager, OutsideCacheManager&... outsideCacheManager)
521 {
522 globalJacobianCache_ = &(leafNodeCache(cacheManager).getGlobalJacobians());
523 }
524
526 {
527 using namespace Impl::Tensor;
528 using namespace Dune::Indices;
529 using LocalBasisTraits = typename Base::LeafNode::FiniteElement::Traits::LocalBasisType::Traits;
530 using Field = typename LocalBasisTraits::RangeFieldType;
531 const auto& globalJacobians = (*globalJacobianCache_)[index];
532 std::size_t size = leafNode().size();
533 std::size_t indexOffset = (size==0) ? 0 : leafNode().localIndex(0);
534 if constexpr(Dune::Fufem::Impl::Concept::LeafTreeNode<Node>)
535 return SparseTensor(_2,
536 [&, size, indexOffset](auto&& f) {
537 for(std::size_t i=0; i<size; ++i)
538 {
539 auto div = Field{0};
540 for(std::size_t j=0; j<globalJacobians[i].N(); ++j)
541 div += globalJacobians[i][j][j];
542 f(div, _0, indexOffset+i);
543 }
544 },
545 size,
547 );
548 else if constexpr(Dune::Fufem::Impl::Concept::UniformInnerTreeNode<Node>
549 and Dune::Fufem::Impl::Concept::LeafTreeNode<Dune::TypeTree::Child<Node, 0>>)
550 return SparseTensor(_2,
551 [&, size, indexOffset](auto&& f) {
552 // Here we should compute the trace of the global Jacobian J
553 // that we would need to build first. But since only the
554 // j-th row of J is nonzero, we can simply
555 // return the diagonal entry of this row which coincides
556 // with the j-th entry of the gradient of
557 // the respective scalar basis function.
558 for(std::size_t j=0; j<Node::degree(); ++j)
559 for(std::size_t i=0; i<size; ++i)
560 f(globalJacobians[i][0][j], _0, indexOffset + j*size + i);
561 },
562 Node::degree() * size,
564 );
565 }
566
567 private:
568 const typename Base::LocalOperator::LeafNodeCache::GlobalJacobianCache* globalJacobianCache_ = nullptr;
569 };
570
572 {
573 return LocalOperator(op);
574 }
575
577 template<std::size_t k>
579 {
580 return {Base::template rebindArgIndex<k>()};
581 }
582
583 };
584
585
586
587} // namespace Dune::Fufem::Forms
588
589
590
591#endif // DUNE_FUFEM_FORMS_UNARYOPERATORS_HH
constexpr index_constant< 0 > _0
int size() const
std::ptrdiff_t index() const
size_t() const
decltype(auto) child(Node &&node, TreePath< Indices... > treePath)
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
void bindToCaches(CacheManager &cacheManager, OutsideCacheManager &... outsideCacheManager)
Definition unaryoperators.hh:520
void bind(const Element &)
Definition unaryoperators.hh:506
void bind(const Intersection &intersection, const Element &element, const Element &otherElement)
Definition unaryoperators.hh:514
typename Base::LocalOperator::Intersection Intersection
Definition unaryoperators.hh:502
typename Base::LocalOperator::CacheManager CacheManager
Definition unaryoperators.hh:503
typename FEFunctionDivergenceOperator::Range Range
Definition unaryoperators.hh:504
auto operator()(std::size_t index) const
Definition unaryoperators.hh:525
Linear map representing the divergenc of the elements of an FE-space.
Definition unaryoperators.hh:474
typename Base::Element Element
Definition unaryoperators.hh:481
friend LocalOperator localOperator(const FEFunctionDivergenceOperator &op)
Definition unaryoperators.hh:571
FEFunctionDivergenceOperator(const Base &other)
Definition unaryoperators.hh:489
FEFunctionDivergenceOperator< B, TP, k > rebindArgIndex() const
Get a copy of this operator bound to another argument.
Definition unaryoperators.hh:578
std::conditional_t< Dune::Fufem::Impl::Concept::LeafTreeNode< Node >, typename LeafLBTraits::RangeFieldType, typename LeafLBTraits::JacobianType::block_type > Range
Definition unaryoperators.hh:485
void bind(const Element &)
Definition unaryoperators.hh:383
void bind(const Intersection &intersection, const Element &element, const Element &otherElement)
Definition unaryoperators.hh:391
typename Base::LocalOperator::Intersection Intersection
Definition unaryoperators.hh:379
typename Base::LocalOperator::CacheManager CacheManager
Definition unaryoperators.hh:380
void bindToCaches(CacheManager &cacheManager, OutsideCacheManager &... outsideCacheManager)
Definition unaryoperators.hh:397
auto operator()(std::size_t index) const
Definition unaryoperators.hh:402
typename FEFunctionJacobianOperator::Range Range
Definition unaryoperators.hh:381
Linear map representing the jacobians of the elements of an FE-space.
Definition unaryoperators.hh:347
typename Impl::GlobalJacobianTraits< ReferenceJacobian, GeometryJacobianInverse >::type Range
Definition unaryoperators.hh:362
FEFunctionJacobianOperator(const Base &other)
Definition unaryoperators.hh:366
FEFunctionJacobianOperator< B, TP, k > rebindArgIndex() const
Get a copy of this operator bound to another argument.
Definition unaryoperators.hh:454
friend LocalOperator localOperator(const FEFunctionJacobianOperator &op)
Definition unaryoperators.hh:439
auto childOperator(Dune::index_constant< i > childIndex) const
Definition unaryoperators.hh:445
typename Base::Element Element
Definition unaryoperators.hh:361
typename Base::LocalOperator::Intersection Intersection
Definition unaryoperators.hh:251
void bind(const Element &)
Definition unaryoperators.hh:255
void bind(const Intersection &intersection, const Element &element, const Element &otherElement)
Definition unaryoperators.hh:263
typename Base::LocalOperator::CacheManager CacheManager
Definition unaryoperators.hh:252
void bindToCaches(CacheManager &cacheManager, OutsideCacheManager &... outsideCacheManager)
Definition unaryoperators.hh:269
auto operator()(std::size_t index) const
Definition unaryoperators.hh:274
typename FEFunctionOperator::Range Range
Definition unaryoperators.hh:253
Linear map representing the elements of an FE-space.
Definition unaryoperators.hh:223
auto childOperator(Dune::index_constant< i > childIndex) const
Definition unaryoperators.hh:317
typename Base::Element Element
Definition unaryoperators.hh:230
FEFunctionOperator< B, TP, k > rebindArgIndex() const
Get a copy of this operator bound to another argument.
Definition unaryoperators.hh:326
FEFunctionOperator(const Base &other)
Definition unaryoperators.hh:238
friend LocalOperator localOperator(const FEFunctionOperator &op)
Definition unaryoperators.hh:311
std::conditional_t< Dune::Fufem::Impl::Concept::LeafTreeNode< Node >, typename LeafLBTraits::RangeType, Dune::FieldVector< typename LeafLBTraits::RangeFieldType, Node::degree()> > Range
Definition unaryoperators.hh:234
bool isAffine_
Definition unaryoperators.hh:177
SubspaceBasis subspaceBasis_
Definition unaryoperators.hh:171
void unbind()
Definition unaryoperators.hh:127
LocalOperator(const SubspaceBasis &subspaceBasis, bool isAffine)
Definition unaryoperators.hh:113
void registerOutsideCaches(CacheManager &cacheManager)
Definition unaryoperators.hh:156
LocalOperator(const FEOperatorBase &op)
Definition unaryoperators.hh:123
const LocalView * localView_
Definition unaryoperators.hh:174
typename FEOperatorBase::Element Element
Definition unaryoperators.hh:109
void registerOutsideLocalViews(const LV &... lvs)
Definition unaryoperators.hh:145
void registerCaches(CacheManager &cacheManager)
Definition unaryoperators.hh:148
auto quadratureRuleKey() const
Definition unaryoperators.hh:130
ShapeFunctionCache< Tree > TreeCache
Definition unaryoperators.hh:104
QuadratureRuleKey quadratureRuleKey_
Definition unaryoperators.hh:175
auto & leafNodeCache(CacheManager &cacheManager)
Definition unaryoperators.hh:166
std::size_t cacheIndex_
Definition unaryoperators.hh:176
void registerLocalViews(const LV &... lvs)
Definition unaryoperators.hh:136
const LeafNode * leafNode_
Definition unaryoperators.hh:173
const LeafTreePath leafTreePath_
Definition unaryoperators.hh:172
const LeafNode & leafNode() const
Definition unaryoperators.hh:161
typename FEOperatorBase::Intersection Intersection
Definition unaryoperators.hh:110
Base class of elementary differential operators on an FE-space.
Definition unaryoperators.hh:62
typename Dune::TypeTree::ChildForTreePath< Tree, TP > Node
Definition unaryoperators.hh:67
typename B::LocalView LocalView
Definition unaryoperators.hh:65
SubspaceBasis subspaceBasis_
Definition unaryoperators.hh:206
typename Dune::TypeTree::ChildForTreePath< Tree, LeafTreePath > LeafNode
Definition unaryoperators.hh:86
B Basis
Definition unaryoperators.hh:87
typename Basis::LocalView::Element Element
Definition unaryoperators.hh:92
bool isAffine_
Definition unaryoperators.hh:207
decltype(leafTreePath(std::declval< TP >())) LeafTreePath
Definition unaryoperators.hh:85
FEOperatorBase(const Basis &basis, const TreePath &treePath, bool isAffine=true)
Definition unaryoperators.hh:95
typename Dune::Functions::SubspaceBasis< B, TP > SubspaceBasis
Definition unaryoperators.hh:68
TP TreePath
Definition unaryoperators.hh:88
static auto leafTreePath(const TP &tp)
Definition unaryoperators.hh:76
typename Basis::GridView::Intersection Intersection
Definition unaryoperators.hh:93
FEOperatorBase< B, TP, k > rebindArgIndex() const
Get a copy of this operator bound to another argument.
Definition unaryoperators.hh:200
typename LocalView::Tree Tree
Definition unaryoperators.hh:66
auto basis() const
Definition unaryoperators.hh:180
auto treePath() const
Definition unaryoperators.hh:185
bool isAffine() const
Definition unaryoperators.hh:190
A hierarchic cache for storing shape function evaluations for a tree.
Definition shapefunctioncache.hh:107
Base class for unary multilinear operator implementations.
Definition baseclass.hh:91
Objects of this class are used to uniquely identifies a cache.
Definition shapefunctioncache.hh:569
A token that specifies a quadrature rule.
Definition quadraturerulecache.hh:39
QuadratureRuleKey derivative() const
Definition quadraturerulecache.hh:154
T forward(T... args)
auto div(const Op &op)
Obtain the divergence of an operator.
Definition userfunctions.hh:1201
Definition baseclass.hh:22
const T & asNumber(const T &t)
Forward given value as number.
Definition asnumber.hh:23
STL namespace.
T tie(T... args)
This header provides fallback implementations for dune-typetree<2.11.