Dune-Fufem 2.11-git
Loading...
Searching...
No Matches
integratedskeletonlinearform.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_INTEGRATEDSKELETONLINEARFORM_HH
8#define DUNE_FUFEM_FORMS_INTEGRATEDSKELETONLINEARFORM_HH
9
10#include <cstddef>
11#include <type_traits>
12#include <utility>
13
17
23
24
25
26namespace Dune::Fufem::Forms {
27
28
29
43 template<class LinearOperator, class Patch, class QuadratureHint=Dune::Fufem::Forms::QuadratureHints::KeepOrder>
45 {
47 using TestRootLocalView = typename TestRootBasis::LocalView;
48 using TestRootTree = typename TestRootLocalView::Tree;
49
50 using LocalOperator = decltype(localOperator(std::declval<LinearOperator>()));
51
53 using QuadratureRule = typename CacheManager::QuadratureRule;
54 using QuadraturePoint = typename QuadratureRule::value_type;
55
56 public:
57 using Element = typename LinearOperator::Element;
58 using Intersection = typename TestRootBasis::GridView::Intersection;
59
60 IntegratedSkeletonLinearForm(const LinearOperator& sumOperator, const Patch& patch, QuadratureHint quadratureHint)
61 : sumOperator_(sumOperator)
62 , sumLocalOperator_(localOperator(sumOperator_))
63 , sumLocalOperatorFlipped_(localOperator(sumOperator_))
64 , patch_(patch)
65 , quadratureHint_(quadratureHint)
66 {}
67
68 IntegratedSkeletonLinearForm(const LinearOperator& sumOperator, const Patch& patch)
70 : IntegratedSkeletonLinearForm(sumOperator, patch, QuadratureHint{})
71 {}
72
74 {
75 return sumOperator_;
76 }
77
78 // Dune::Assembler interface
79
80 void bindLocalView (const TestRootLocalView& testLocalView)
81 {
82 sumLocalOperator_.registerLocalViews(testLocalView.rootLocalView());
83 sumLocalOperator_.registerCaches(insideCache_);
84 sumLocalOperatorFlipped_.registerOutsideLocalViews(testLocalView.rootLocalView());
85 sumLocalOperatorFlipped_.registerOutsideCaches(insideCache_);
86 insidePtr_ = &testLocalView.element();
87 }
88
89 void bindOutsideLocalView (const TestRootLocalView& testLocalView)
90 {
91 sumLocalOperator_.registerOutsideLocalViews(testLocalView.rootLocalView());
92 sumLocalOperator_.registerOutsideCaches(outsideCache_);
93 sumLocalOperatorFlipped_.registerLocalViews(testLocalView.rootLocalView());
94 sumLocalOperatorFlipped_.registerCaches(outsideCache_);
95 outsidePtr_ = &testLocalView.element();
96 }
97
98 void bindElement (const Element& element)
99 {}
100
101 template <class LocalVectors>
102 void assembleInteriorIntersectionVector (const Intersection& intersection, LocalVectors& localVectors)
103 {
104 using namespace Dune::Indices;
105 using namespace Dune::Fufem::Forms::Impl::Tensor;
106
107 if (not patch_.contains(intersection))
108 return;
109
110 bool isOriented = true;
111 if constexpr (requires { patch_.isOriented(intersection); })
112 isOriented = patch_.isOriented(intersection);
113
114 // LocalVectors only supports localVectors[i][j] and localVectors[i](j).
115 // The TensorView provides the unified access via localTensor(i,j).
116 auto localTensor = TensorView(localVectors, _2);
117
118 if (isOriented)
119 {
120 sumLocalOperator_.bind(intersection, *insidePtr_, *outsidePtr_);
121
122 const auto& geometry = intersection.geometry();
123 const auto& geometryInInside = intersection.geometryInInside();
124 const auto& geometryInOutside = intersection.geometryInOutside();
125
126 // Since we will often have many boundary terms (e.g. for DG)
127 // while evaluations are currently not cached across elements,
128 // we use a single quadrature rule for all addends despite the
129 // fact that a lower order might also be sufficient for some of them.
130 auto key = quadratureHint_(sumLocalOperator_.quadratureRuleKey());
131 key.setGeometryType(geometry.type());
133
134 // Notice that we cannot easily cache evaluation by identifying quadrature rules
135 // on intersections across different elements. To guarantee that quadrature
136 // points match up on inside and outside, we have to compute the element coordinates
137 // of intersection quadrature points using the intersection. This has the effect
138 // that the e.g. points on face 2 may be different on two elements because the
139 // intersections are not oriented consistently. The latter problem could be solved
140 // by computing the element coordinates using the reference element embedding, but
141 // then inside and outside quadrature points would not match up.
142 //
143 // Hence we take the intersection approach (which is also robust wrt. non-conforming
144 // intersections) and do not cache across different intersections so far.
145 // Since the operator expects a cache, we use caches that are reset for any intersection.
146 insideRule_.resize(rule.size(), QuadraturePoint(typename QuadraturePoint::Vector(), 0));
147 for (auto k : Dune::range(rule.size()))
148 insideRule_[k] = QuadraturePoint(geometryInInside.global(rule[k].position()), 0);
149 insideCache_.setRule(insideRule_);
150
151 outsideRule_.resize(rule.size(), QuadraturePoint(typename QuadraturePoint::Vector(), 0));
152 for (auto k : Dune::range(rule.size()))
153 outsideRule_[k] = QuadraturePoint(geometryInOutside.global(rule[k].position()), 0);
154 outsideCache_.setRule(outsideRule_);
155
156 sumLocalOperator_.bindToCaches(insideCache_, outsideCache_);
157
158 for (auto k : Dune::range(rule.size()))
159 {
160 Impl::forEachTupleEntry(sumLocalOperator_.operators(), [&](auto& op) {
161 const auto integrationWeight = rule[k].weight() * geometry.integrationElement(rule[k].position());
162 axpy(integrationWeight, op(k), localTensor);
163 });
164 }
165 }
166 else
167 {
168 // If the intersection is not oriented, we need to flip the leading index
169 auto flippedLocalTensor = FlipIndices(localTensor, _1);
170
171 sumLocalOperatorFlipped_.bind(intersection, *outsidePtr_, *insidePtr_);
172
173 const auto& geometry = intersection.geometry();
174 const auto& geometryInInside = intersection.geometryInInside();
175 const auto& geometryInOutside = intersection.geometryInOutside();
176
177 // Since we will often have many boundary terms (e.g. for DG)
178 // while evaluations are currently not cached across elements,
179 // we use a single quadrature rule for all addends despite the
180 // fact that a lower order might also be sufficient for some of them.
181 auto key = quadratureHint_(sumLocalOperatorFlipped_.quadratureRuleKey());
182 key.setGeometryType(geometry.type());
184
185 // Notice that we cannot easily cache evaluation by identifying quadrature rules
186 // on intersections across different elements. To guarantee that quadrature
187 // points match up on inside and outside, we have to compute the element coordinates
188 // of intersection quadrature points using the intersection. This has the effect
189 // that the e.g. points on face 2 may be different on two elements because the
190 // intersections are not oriented consistently. The latter problem could be solved
191 // by computing the element coordinates using the reference element embedding, but
192 // then inside and outside quadrature points would not match up.
193 //
194 // Hence we take the intersection approach (which is also robust wrt. non-conforming
195 // intersections) and do not cache across different intersections so far.
196 // Since the operator expects a cache, we use caches that are reset for any intersection.
197 insideRule_.resize(rule.size(), QuadraturePoint(typename QuadraturePoint::Vector(), 0));
198 for (auto k : Dune::range(rule.size()))
199 insideRule_[k] = QuadraturePoint(geometryInInside.global(rule[k].position()), 0);
200 insideCache_.setRule(insideRule_);
201
202 outsideRule_.resize(rule.size(), QuadraturePoint(typename QuadraturePoint::Vector(), 0));
203 for (auto k : Dune::range(rule.size()))
204 outsideRule_[k] = QuadraturePoint(geometryInOutside.global(rule[k].position()), 0);
205 outsideCache_.setRule(outsideRule_);
206
207 sumLocalOperatorFlipped_.bindToCaches(outsideCache_, insideCache_);
208
209 for (auto k : Dune::range(rule.size()))
210 {
211 Impl::forEachTupleEntry(sumLocalOperatorFlipped_.operators(), [&](auto& op) {
212 const auto integrationWeight = rule[k].weight() * geometry.integrationElement(rule[k].position());
213 axpy(integrationWeight, op(k), flippedLocalTensor);
214 });
215 }
216 }
217
218 }
219
220 private:
221 const LinearOperator sumOperator_;
222 mutable LocalOperator sumLocalOperator_;
223 mutable LocalOperator sumLocalOperatorFlipped_;
224 const Element* insidePtr_ = nullptr;
225 const Element* outsidePtr_ = nullptr;
226 mutable QuadratureRule insideRule_;
227 mutable QuadratureRule outsideRule_;
228 CacheManager insideCache_;
229 CacheManager outsideCache_;
230 const Patch& patch_;
231 QuadratureHint quadratureHint_;
232 };
233
234 template<class LinearOperator, class Patch>
236
237
238
239 template<class LinearOperator, class Patch, class QuadratureHint>
241
242
243
244} // namespace Dune::Fufem::Forms
245
246
247#endif // DUNE_FUFEM_FORMS_INTEGRATEDSKELETONLINEARFORM_HH
static constexpr IntegralRange< T > range(T from, T to) noexcept
Definition baseclass.hh:22
Local assembler corresponding to a skeleton linear form.
Definition integratedskeletonlinearform.hh:45
void assembleInteriorIntersectionVector(const Intersection &intersection, LocalVectors &localVectors)
Definition integratedskeletonlinearform.hh:102
void bindLocalView(const TestRootLocalView &testLocalView)
Definition integratedskeletonlinearform.hh:80
typename LinearOperator::Element Element
Definition integratedskeletonlinearform.hh:57
void bindElement(const Element &element)
Definition integratedskeletonlinearform.hh:98
IntegratedSkeletonLinearForm(const LinearOperator &sumOperator, const Patch &patch, QuadratureHint quadratureHint)
Definition integratedskeletonlinearform.hh:60
const LinearOperator & integrandOperator() const
Definition integratedskeletonlinearform.hh:73
typename TestRootBasis::GridView::Intersection Intersection
Definition integratedskeletonlinearform.hh:58
IntegratedSkeletonLinearForm(const LinearOperator &sumOperator, const Patch &patch)
Definition integratedskeletonlinearform.hh:68
void bindOutsideLocalView(const TestRootLocalView &testLocalView)
Definition integratedskeletonlinearform.hh:89
Definition localsumassembler.hh:80
A class for managing caches of different types.
Definition shapefunctioncache.hh:612
Dune::QuadratureRule< CT, dimension > QuadratureRule
Definition shapefunctioncache.hh:614
static const Dune::QuadratureRule< coord_type, dim > & rule(const Dune::GeometryType &gt, const int order, int refinement)
Definition quadraturerulecache.hh:196
T forward(T... args)