Dune-Fufem 2.12-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
23
25
27
31
33
34
35
36namespace Dune::Fufem::Forms {
37
38
39
53 template<class B, class TP, std::size_t argIndex>
54 class FEOperatorBase : public UnaryOperator<argIndex>
55 {
56
57 protected:
58 using LocalView = typename B::LocalView;
59 using Tree = typename LocalView::Tree;
62
63 // Helper function to derive the leafTreePath associated
64 // to a treePath. For treePaths referring to a leaf this is
65 // the identity. For treePaths referring to the a power
66 // node whose children are leaf, it's the first child.
67 // This is used to implement vector valued ansatz functions
68 // for power nodes.
69 static auto leafTreePath(const TP& tp)
70 {
72 return tp;
75 return Dune::TypeTree::push_back(tp, Dune::Indices::_0);
76 }
77
80 using Basis = B;
81 using TreePath = TP;
82
83 public:
84
85 using Element = typename Basis::LocalView::Element;
86 using Intersection = typename Basis::GridView::Intersection;
87
88 FEOperatorBase(const Basis& basis, const TreePath& treePath, bool isAffine = true) :
91 {}
92
94 {
95 protected:
96
99
100 public:
101
105
106 LocalOperator(const SubspaceBasis& subspaceBasis, bool isAffine) :
107 subspaceBasis_(subspaceBasis),
109 leafNode_(nullptr),
110 localView_(nullptr),
112 cacheIndex_(std::numeric_limits<std::size_t>::max()),
114 {}
115
118 {}
119
120 void unbind()
121 {}
122
123 auto quadratureRuleKey() const
124 {
125 return quadratureRuleKey_;
126 }
127
128 template<class... LV>
129 void registerLocalViews(const LV&... lvs)
130 {
131 Impl::visitMatchingLocalView([&](const auto& localView) {
132 localView_ = &localView;
133 leafNode_ = & Dune::TypeTree::child(localView.tree(), leafTreePath_);
134 }, subspaceBasis_.rootBasis(), lvs...);
135 }
136
137 template<class... LV>
138 void registerOutsideLocalViews(const LV&... lvs)
139 {}
140
141 void registerCaches(CacheManager& cacheManager)
142 {
143 const auto& tree = localView_->tree();
144 cacheIndex_ = cacheManager.registerCache(UniqueCacheId(tree), TreeCache(tree));
145 if (not isAffine_)
146 cacheManager.template getCache<TreeCache>(cacheIndex_)[subspaceBasis_.prefixPath()].setNonAffine();
147 }
148
150 {}
151
152 protected:
153
154 const LeafNode& leafNode() const
155 {
156 return *leafNode_;
157 }
158
159 auto& leafNodeCache(CacheManager& cacheManager)
160 {
161 return cacheManager.template getCache<TreeCache>(cacheIndex_)[leafTreePath_];
162 }
163
171 };
172
173 auto basis() const
174 {
175 return std::tie(subspaceBasis_.rootBasis());
176 }
177
178 auto treePath() const
179 {
180 return std::tie(subspaceBasis_.prefixPath());
181 }
182
183 bool isAffine() const
184 {
185 return isAffine_;
186 }
187
192 template<std::size_t k>
194 {
196 }
197
198 protected:
201 };
202
203
204
214 template<class B, class TP, std::size_t argIndex>
215 class FEFunctionOperator : public FEOperatorBase<B, TP, argIndex>
216 {
218 using Node = typename Base::Node;
219 using LeafLBTraits = typename Base::LeafNode::FiniteElement::Traits::LocalBasisType::Traits;
220
221 public:
222
223 using Element = typename Base::Element;
226 typename LeafLBTraits::RangeType,
227 Dune::FieldVector<typename LeafLBTraits::RangeFieldType, Node::degree()>>;
228
229 using Base::Base;
230
232 : Base(other)
233 {}
234
236 {
237 using Base::LocalOperator::quadratureRuleKey_;
238 using Base::LocalOperator::leafNode;
239 using Base::LocalOperator::leafNodeCache;
241
242 public:
243
245 using CacheManager = typename Base::LocalOperator::CacheManager;
247
248 void bind(const Element&)
249 {
250 if (leafNode().size()!=0)
251 quadratureRuleKey_ = QuadratureRuleKey(leafNode().finiteElement());
252 else
253 quadratureRuleKey_ = QuadratureRuleKey(this->localView_->element().type(), 0);
254 }
255
256 void bind(const Intersection& intersection, const Element& element, const Element& otherElement)
257 {
258 bind(element);
259 }
260
261 template<class... OutsideCacheManager>
262 void bindToCaches(CacheManager& cacheManager, OutsideCacheManager&... outsideCacheManager)
263 {
264 valueCache_ = &(leafNodeCache(cacheManager).getValues());
265 }
266
268 {
269 using namespace Impl::Tensor;
270 using namespace Dune::Indices;
271 const auto& values = (*valueCache_)[index];
272 std::size_t size = leafNode().size();
273 std::size_t indexOffset = (size==0) ? 0 : leafNode().localIndex(0);
275 return SparseTensor(_2,
276 [&, size, indexOffset](auto&& f) {
277 for(std::size_t i=0; i<size; ++i)
278 f(values[i], _0, indexOffset+i);
279 },
280 size,
282 );
285 return SparseTensor(_2,
286 [&, size, indexOffset](auto&& f) {
287 for(std::size_t j=0; j<Node::degree(); ++j)
288 for(std::size_t i=0; i<size; ++i)
289 {
290 auto result = Range(0);
291 result[j] = Dune::Fufem::asNumber(values[i]);
292 f(result, _0, indexOffset + j*size + i);
293 }
294 },
295 Node::degree() * size,
297 );
298 }
299
300 private:
301 const typename Base::LocalOperator::LeafNodeCache::ValueCache* valueCache_ = nullptr;
302 };
303
305 {
306 return LocalOperator(op);
307 }
308
309 template<std::size_t i>
311 {
312 using Basis = typename Base::Basis;
313 auto childTP = Dune::TypeTree::push_back(Base::subspaceBasis_.prefixPath(), childIndex);
315 }
316
318 template<std::size_t k>
320 {
321 return {Base::template rebindArgIndex<k>()};
322 }
323
324 };
325
326
327
328
338 template<class B, class TP, std::size_t argIndex>
339 class FEFunctionJacobianOperator : public FEOperatorBase<B, TP, argIndex>
340 {
342 using Node = typename Base::Node;
343 using LeafLBTraits = typename Base::LeafNode::FiniteElement::Traits::LocalBasisType::Traits;
344
347 typename LeafLBTraits::JacobianType,
348 Dune::FieldMatrix<typename LeafLBTraits::RangeFieldType, Node::degree(), LeafLBTraits::dimDomain>>;
349
350 using GeometryJacobianInverse = typename Node::Element::Geometry::JacobianInverse;
351
352 public:
353
354 using Element = typename Base::Element;
355 using Range = typename Impl::GlobalJacobianTraits<ReferenceJacobian, GeometryJacobianInverse>::type;
356
357 using Base::Base;
358
360 : Base(other)
361 {}
362
364 {
365 using Base::LocalOperator::quadratureRuleKey_;
366 using Base::LocalOperator::leafNode;
367 using Base::LocalOperator::leafNodeCache;
369
370 public:
371
373 using CacheManager = typename Base::LocalOperator::CacheManager;
375
376 void bind(const Element&)
377 {
378 if (leafNode().size()!=0)
380 else
381 quadratureRuleKey_ = QuadratureRuleKey(this->localView_->element().type(), 0);
382 }
383
384 void bind(const Intersection& intersection, const Element& element, const Element& otherElement)
385 {
386 bind(element);
387 }
388
389 template<class... OutsideCacheManager>
390 void bindToCaches(CacheManager& cacheManager, OutsideCacheManager&... outsideCacheManager)
391 {
392 globalJacobianCache_ = &(leafNodeCache(cacheManager).getGlobalJacobians());
393 }
394
396 {
397 using namespace Impl::Tensor;
398 using namespace Dune::Indices;
399 const auto& globalJacobians = (*globalJacobianCache_)[index];
400 std::size_t size = leafNode().size();
401 std::size_t indexOffset = (size==0) ? 0 : leafNode().localIndex(0);
403 return SparseTensor(_2,
404 [&, size, indexOffset](auto&& f) {
405 for(std::size_t i=0; i<size; ++i)
406 f(globalJacobians[i], _0, indexOffset+i);
407 },
408 size,
410 );
413 return SparseTensor(_2,
414 [&, size, indexOffset](auto&& f) {
415 for(std::size_t j=0; j<Node::degree(); ++j)
416 for(std::size_t i=0; i<size; ++i)
417 {
418 auto result = Range(0);
419 result[j] = globalJacobians[i][0];
420 f(result, _0, indexOffset + j*size + i);
421 }
422 },
423 Node::degree() * size,
425 );
426 }
427
428 private:
429 const typename Base::LocalOperator::LeafNodeCache::GlobalJacobianCache* globalJacobianCache_ = nullptr;
430 };
431
433 {
434 return LocalOperator(op);
435 }
436
437 template<std::size_t i>
439 {
440 using Basis = typename Base::Basis;
441 auto childTP = Dune::TypeTree::push_back(Base::subspaceBasis_.prefixPath(), childIndex);
443 }
444
446 template<std::size_t k>
448 {
449 return {Base::template rebindArgIndex<k>()};
450 }
451
452 };
453
454
455
465 template<class B, class TP, std::size_t argIndex>
466 class FEFunctionDivergenceOperator : public FEOperatorBase<B, TP, argIndex>
467 {
469 using Node = typename Base::Node;
470 using LeafLBTraits = typename Base::LeafNode::FiniteElement::Traits::LocalBasisType::Traits;
471
472 public:
473
474 using Element = typename Base::Element;
477 typename LeafLBTraits::RangeFieldType,
478 typename LeafLBTraits::JacobianType::block_type>;
479
480 using Base::Base;
481
483 : Base(other)
484 {}
485
487 {
488 using Base::LocalOperator::quadratureRuleKey_;
489 using Base::LocalOperator::leafNode;
490 using Base::LocalOperator::leafNodeCache;
492
493 public:
494
496 using CacheManager = typename Base::LocalOperator::CacheManager;
498
499 void bind(const Element&)
500 {
501 if (leafNode().size()!=0)
503 else
504 quadratureRuleKey_ = QuadratureRuleKey(this->localView_->element().type(), 0);
505 }
506
507 void bind(const Intersection& intersection, const Element& element, const Element& otherElement)
508 {
509 bind(element);
510 }
511
512 template<class... OutsideCacheManager>
513 void bindToCaches(CacheManager& cacheManager, OutsideCacheManager&... outsideCacheManager)
514 {
515 globalJacobianCache_ = &(leafNodeCache(cacheManager).getGlobalJacobians());
516 }
517
519 {
520 using namespace Impl::Tensor;
521 using namespace Dune::Indices;
522 using LocalBasisTraits = typename Base::LeafNode::FiniteElement::Traits::LocalBasisType::Traits;
523 using Field = typename LocalBasisTraits::RangeFieldType;
524 const auto& globalJacobians = (*globalJacobianCache_)[index];
525 std::size_t size = leafNode().size();
526 std::size_t indexOffset = (size==0) ? 0 : leafNode().localIndex(0);
528 return SparseTensor(_2,
529 [&, size, indexOffset](auto&& f) {
530 for(std::size_t i=0; i<size; ++i)
531 {
532 auto div = Field{0};
533 for(std::size_t j=0; j<globalJacobians[i].N(); ++j)
534 div += globalJacobians[i][j][j];
535 f(div, _0, indexOffset+i);
536 }
537 },
538 size,
540 );
543 return SparseTensor(_2,
544 [&, size, indexOffset](auto&& f) {
545 // Here we should compute the trace of the global Jacobian J
546 // that we would need to build first. But since only the
547 // j-th row of J is nonzero, we can simply
548 // return the diagonal entry of this row which coincides
549 // with the j-th entry of the gradient of
550 // the respective scalar basis function.
551 for(std::size_t j=0; j<Node::degree(); ++j)
552 for(std::size_t i=0; i<size; ++i)
553 f(globalJacobians[i][0][j], _0, indexOffset + j*size + i);
554 },
555 Node::degree() * size,
557 );
558 }
559
560 private:
561 const typename Base::LocalOperator::LeafNodeCache::GlobalJacobianCache* globalJacobianCache_ = nullptr;
562 };
563
565 {
566 return LocalOperator(op);
567 }
568
570 template<std::size_t k>
572 {
573 return {Base::template rebindArgIndex<k>()};
574 }
575
576 };
577
578
579
580} // namespace Dune::Fufem::Forms
581
582
583
584#endif // DUNE_FUFEM_FORMS_UNARYOPERATORS_HH
int size() const
std::ptrdiff_t index() const
size_t() const
decltype(auto) child(Node &&node, TreePath< Indices... > treePath)
constexpr index_constant< 0 > _0
A class for managing caches of different types.
Definition shapefunctioncache.hh:609
size_type registerCache(UniqueCacheId uniqueCacheId, Cache &&cache)
Register a new cache.
Definition shapefunctioncache.hh:747
void bindToCaches(CacheManager &cacheManager, OutsideCacheManager &... outsideCacheManager)
Definition unaryoperators.hh:513
void bind(const Element &)
Definition unaryoperators.hh:499
void bind(const Intersection &intersection, const Element &element, const Element &otherElement)
Definition unaryoperators.hh:507
typename Base::LocalOperator::Intersection Intersection
Definition unaryoperators.hh:495
typename Base::LocalOperator::CacheManager CacheManager
Definition unaryoperators.hh:496
typename FEFunctionDivergenceOperator::Range Range
Definition unaryoperators.hh:497
auto operator()(std::size_t index) const
Definition unaryoperators.hh:518
Linear map representing the divergenc of the elements of an FE-space.
Definition unaryoperators.hh:467
typename Base::Element Element
Definition unaryoperators.hh:474
std::conditional_t< Dune::TypeTree::Concept::LeafTreeNode< Node >, typename LeafLBTraits::RangeFieldType, typename LeafLBTraits::JacobianType::block_type > Range
Definition unaryoperators.hh:478
friend LocalOperator localOperator(const FEFunctionDivergenceOperator &op)
Definition unaryoperators.hh:564
FEFunctionDivergenceOperator(const Base &other)
Definition unaryoperators.hh:482
FEFunctionDivergenceOperator< B, TP, k > rebindArgIndex() const
Get a copy of this operator bound to another argument.
Definition unaryoperators.hh:571
void bind(const Element &)
Definition unaryoperators.hh:376
void bind(const Intersection &intersection, const Element &element, const Element &otherElement)
Definition unaryoperators.hh:384
typename Base::LocalOperator::Intersection Intersection
Definition unaryoperators.hh:372
typename Base::LocalOperator::CacheManager CacheManager
Definition unaryoperators.hh:373
void bindToCaches(CacheManager &cacheManager, OutsideCacheManager &... outsideCacheManager)
Definition unaryoperators.hh:390
auto operator()(std::size_t index) const
Definition unaryoperators.hh:395
typename FEFunctionJacobianOperator::Range Range
Definition unaryoperators.hh:374
Linear map representing the jacobians of the elements of an FE-space.
Definition unaryoperators.hh:340
typename Impl::GlobalJacobianTraits< ReferenceJacobian, GeometryJacobianInverse >::type Range
Definition unaryoperators.hh:355
FEFunctionJacobianOperator(const Base &other)
Definition unaryoperators.hh:359
FEFunctionJacobianOperator< B, TP, k > rebindArgIndex() const
Get a copy of this operator bound to another argument.
Definition unaryoperators.hh:447
friend LocalOperator localOperator(const FEFunctionJacobianOperator &op)
Definition unaryoperators.hh:432
auto childOperator(Dune::index_constant< i > childIndex) const
Definition unaryoperators.hh:438
typename Base::Element Element
Definition unaryoperators.hh:354
typename Base::LocalOperator::Intersection Intersection
Definition unaryoperators.hh:244
void bind(const Element &)
Definition unaryoperators.hh:248
void bind(const Intersection &intersection, const Element &element, const Element &otherElement)
Definition unaryoperators.hh:256
typename Base::LocalOperator::CacheManager CacheManager
Definition unaryoperators.hh:245
void bindToCaches(CacheManager &cacheManager, OutsideCacheManager &... outsideCacheManager)
Definition unaryoperators.hh:262
auto operator()(std::size_t index) const
Definition unaryoperators.hh:267
typename FEFunctionOperator::Range Range
Definition unaryoperators.hh:246
Linear map representing the elements of an FE-space.
Definition unaryoperators.hh:216
std::conditional_t< Dune::TypeTree::Concept::LeafTreeNode< Node >, typename LeafLBTraits::RangeType, Dune::FieldVector< typename LeafLBTraits::RangeFieldType, Node::degree()> > Range
Definition unaryoperators.hh:227
auto childOperator(Dune::index_constant< i > childIndex) const
Definition unaryoperators.hh:310
typename Base::Element Element
Definition unaryoperators.hh:223
FEFunctionOperator< B, TP, k > rebindArgIndex() const
Get a copy of this operator bound to another argument.
Definition unaryoperators.hh:319
FEFunctionOperator(const Base &other)
Definition unaryoperators.hh:231
friend LocalOperator localOperator(const FEFunctionOperator &op)
Definition unaryoperators.hh:304
bool isAffine_
Definition unaryoperators.hh:170
SubspaceBasis subspaceBasis_
Definition unaryoperators.hh:164
void unbind()
Definition unaryoperators.hh:120
LocalOperator(const SubspaceBasis &subspaceBasis, bool isAffine)
Definition unaryoperators.hh:106
void registerOutsideCaches(CacheManager &cacheManager)
Definition unaryoperators.hh:149
LocalOperator(const FEOperatorBase &op)
Definition unaryoperators.hh:116
const LocalView * localView_
Definition unaryoperators.hh:167
typename FEOperatorBase::Element Element
Definition unaryoperators.hh:102
void registerOutsideLocalViews(const LV &... lvs)
Definition unaryoperators.hh:138
void registerCaches(CacheManager &cacheManager)
Definition unaryoperators.hh:141
auto quadratureRuleKey() const
Definition unaryoperators.hh:123
ShapeFunctionCache< Tree > TreeCache
Definition unaryoperators.hh:97
QuadratureRuleKey quadratureRuleKey_
Definition unaryoperators.hh:168
auto & leafNodeCache(CacheManager &cacheManager)
Definition unaryoperators.hh:159
std::size_t cacheIndex_
Definition unaryoperators.hh:169
void registerLocalViews(const LV &... lvs)
Definition unaryoperators.hh:129
const LeafNode * leafNode_
Definition unaryoperators.hh:166
const LeafTreePath leafTreePath_
Definition unaryoperators.hh:165
const LeafNode & leafNode() const
Definition unaryoperators.hh:154
typename FEOperatorBase::Intersection Intersection
Definition unaryoperators.hh:103
Base class of elementary differential operators on an FE-space.
Definition unaryoperators.hh:55
typename Dune::TypeTree::ChildForTreePath< Tree, TP > Node
Definition unaryoperators.hh:60
typename B::LocalView LocalView
Definition unaryoperators.hh:58
SubspaceBasis subspaceBasis_
Definition unaryoperators.hh:199
typename Dune::TypeTree::ChildForTreePath< Tree, LeafTreePath > LeafNode
Definition unaryoperators.hh:79
B Basis
Definition unaryoperators.hh:80
typename Basis::LocalView::Element Element
Definition unaryoperators.hh:85
bool isAffine_
Definition unaryoperators.hh:200
decltype(leafTreePath(std::declval< TP >())) LeafTreePath
Definition unaryoperators.hh:78
FEOperatorBase(const Basis &basis, const TreePath &treePath, bool isAffine=true)
Definition unaryoperators.hh:88
typename Dune::Functions::SubspaceBasis< B, TP > SubspaceBasis
Definition unaryoperators.hh:61
TP TreePath
Definition unaryoperators.hh:81
static auto leafTreePath(const TP &tp)
Definition unaryoperators.hh:69
typename Basis::GridView::Intersection Intersection
Definition unaryoperators.hh:86
FEOperatorBase< B, TP, k > rebindArgIndex() const
Get a copy of this operator bound to another argument.
Definition unaryoperators.hh:193
typename LocalView::Tree Tree
Definition unaryoperators.hh:59
auto basis() const
Definition unaryoperators.hh:173
auto treePath() const
Definition unaryoperators.hh:178
bool isAffine() const
Definition unaryoperators.hh:183
A hierarchic cache for storing shape function evaluations for a tree.
Definition shapefunctioncache.hh:101
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:563
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:1195
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)