3 #include <amdis/Output.hpp> 4 #include <amdis/algorithm/ForEach.hpp> 5 #include <amdis/common/DerivativeTraits.hpp> 6 #include <amdis/common/FieldMatVec.hpp> 7 #include <amdis/common/Index.hpp> 8 #include <amdis/common/Math.hpp> 9 #include <amdis/functions/HierarchicNodeToRangeMap.hpp> 10 #include <amdis/functions/NodeIndices.hpp> 11 #include <amdis/functions/Order.hpp> 12 #include <amdis/typetree/FiniteElementType.hpp> 13 #include <amdis/utility/LocalToGlobalAdapter.hpp> 15 #include <dune/common/ftraits.hh> 21 template <
class Coeff,
class LV,
class LC>
22 auto gather(Coeff
const& coeff, LV
const& localView, LC& localCoeff, Dune::PriorityTag<2>)
23 -> std::void_t<decltype(coeff.gather(localView, localCoeff))>
25 coeff.gather(localView, localCoeff);
29 template <
class Coeff,
class LV,
class LC,
31 auto gather(Coeff
const& coeff, LV
const& localView, LC& localCoeff, Dune::PriorityTag<1>)
32 -> std::void_t<decltype(coeff[std::declval<MI>()])>
34 localCoeff.resize(localView.size());
35 auto it = localCoeff.begin();
36 for (
auto const& idx : nodeIndices(localView))
41 template <
class Coeff,
class LV,
class LC>
42 auto gather(Coeff
const& coeff, LV
const& localView, LC& localCoeff, Dune::PriorityTag<0>)
43 -> std::void_t<decltype(coeff[index_<0>])>
45 auto backend = Dune::Functions::istlVectorBackend(coeff);
46 localCoeff.resize(localView.size());
47 auto it = localCoeff.begin();
48 for (
auto const& idx : nodeIndices(localView))
55 template <
class C,
class GB,
class TP,
class R>
59 using DomainType =
typename DiscreteFunction::Domain;
60 using RangeType =
typename DiscreteFunction::Range;
66 using Domain =
typename EntitySet::LocalCoordinate;
67 using Range = DerivativeRange<Type>;
69 enum { hasDerivative = std::is_same<Type, tag::value>::value };
73 using Element =
typename EntitySet::Element;
74 using Geometry =
typename Element::Geometry;
80 LocalFunction(std::shared_ptr<LV> localView, TP
const& treePath, C
const& coefficients, Type type)
81 : localView_(
std::move(localView))
83 , coefficients_(coefficients)
88 void bind(Element
const& element)
90 localView_->bind(element);
91 geometry_.emplace(element.geometry());
92 Impl::gather(coefficients_, *localView_, localCoefficients_, Dune::PriorityTag<4>{});
105 Range operator() (
const Domain& local)
const 108 if constexpr (std::is_same_v<Type, tag::value>)
109 return evaluateFunction(local);
110 else if constexpr (std::is_same_v<Type, tag::gradient>)
111 return evaluateJacobian(local);
112 else if constexpr (std::is_same_v<Type, tag::partial>)
113 return evaluatePartialDerivative(local);
114 else if constexpr (std::is_same_v<Type, tag::divergence>) {
115 static constexpr
bool isVectorNode
116 = SubTree::isPower &&
int(SubTree::degree()) == GridView::dimensionworld;
117 static_assert(isVectorNode);
118 if constexpr (isVectorNode)
119 return evaluateDivergence(local);
126 template <
class DerType>
129 static_assert(std::is_same_v<Type, tag::value>);
130 return {localView_, treePath_, coefficients_, type};
135 -> decltype(
AMDiS::order(
std::declval<SubTree>()))
138 return AMDiS::order(subTree());
145 return localView_->element();
150 template <
class LocalCoordinate>
151 auto evaluateFunction (
const LocalCoordinate& local)
const;
153 template <
class LocalCoordinate>
154 auto evaluateJacobian (
const LocalCoordinate& local)
const;
156 template <
class LocalCoordinate>
157 auto evaluateDivergence (
const LocalCoordinate& local)
const;
159 template <
class LocalCoordinate>
160 auto evaluatePartialDerivative (
const LocalCoordinate& local)
const;
163 Geometry
const& geometry()
const 170 SubTree
const& subTree()
const 172 return Dune::TypeTree::child(localView_->tree(), treePath_);
178 class = decltype(std::declval<LV>().treeCache())>
179 auto const& subTreeCache(Dune::PriorityTag<1>)
const 181 return Dune::TypeTree::child(localView_->treeCache(), treePath_);
186 auto subTreeCache(Dune::PriorityTag<0>)
const 188 return makeNodeCache(subTree());
191 decltype(
auto) subTreeCache()
const 193 return subTreeCache<LocalView>(Dune::PriorityTag<2>());
197 std::shared_ptr<LocalView> localView_;
199 Coefficients
const& coefficients_;
203 std::optional<Geometry> geometry_;
204 std::vector<Coefficient> localCoefficients_;
209 template <
class C,
class GB,
class TP,
class R>
210 template <
class Type>
211 template <
class LocalCoordinate>
216 Recursive::forEach(y, [](
auto& v) { v = 0; });
218 Traversal::forEachLeafNode(this->subTreeCache(), [&](
auto const& node,
auto const& tp)
220 auto const& shapeFunctionValues = node.localBasisValuesAt(local);
221 std::size_t size = node.finiteElement().size();
224 auto re = Dune::Functions::flatVectorView(nodeToRangeMap_(node, tp, y));
226 for (std::size_t i = 0; i < size; ++i) {
228 auto c = Dune::Functions::flatVectorView(localCoefficients_[node.localIndex(i)]);
231 auto v = Dune::Functions::flatVectorView(shapeFunctionValues[i]);
233 std::size_t dimC = c.size();
234 std::size_t dimV = v.size();
235 assert(dimC*dimV == std::size_t(re.size()));
236 for(std::size_t j = 0; j < dimC; ++j) {
238 for(std::size_t k = 0; k < dimV; ++k)
239 re[j*dimV + k] += c_j*v[k];
248 template <
class C,
class GB,
class TP,
class R>
249 template <
class Type>
250 template <
class LocalCoordinate>
255 Recursive::forEach(dy, [](
auto& v) { v = 0; });
257 Traversal::forEachLeafNode(this->subTreeCache(), [&](
auto const& node,
auto const& tp)
260 auto const& gradients = localBasis.
gradientsAt(local);
263 auto re = Dune::Functions::flatVectorView(nodeToRangeMap_(node, tp, dy));
265 for (std::size_t i = 0; i < localBasis.
size(); ++i) {
267 auto c = Dune::Functions::flatVectorView(localCoefficients_[node.localIndex(i)]);
270 auto grad = Dune::Functions::flatVectorView(gradients[i]);
272 std::size_t dimC = c.size();
273 std::size_t dimV = grad.size();
274 assert(dimC*dimV == std::size_t(re.size()));
275 for(std::size_t j = 0; j < dimC; ++j) {
277 for(std::size_t k = 0; k < dimV; ++k)
278 re[j*dimV + k] += c_j*grad[k];
287 template <
class C,
class GB,
class TP,
class R>
288 template <
class Type>
289 template <
class LocalCoordinate>
293 static_assert(static_size_v<Range> == 1,
"Divergence implemented for scalar coefficients only.");
296 Recursive::forEach(dy, [](
auto& v) { v = 0; });
298 auto&& node = this->subTreeCache();
301 auto const& gradients = localBasis.
gradientsAt(local);
303 auto re = Dune::Functions::flatVectorView(dy);
304 assert(
int(re.size()) == 1);
305 for (std::size_t i = 0; i < localBasis.size(); ++i) {
306 auto grad = Dune::Functions::flatVectorView(gradients[i]);
308 assert(
int(grad.size()) == GridView::dimensionworld);
309 for (std::size_t j = 0; j < GridView::dimensionworld; ++j)
310 re[0] += localCoefficients_[node.child(j).localIndex(i)] * grad[j];
317 template <
class C,
class GB,
class TP,
class R>
318 template <
class Type>
319 template <
class LocalCoordinate>
323 std::size_t comp = this->type_.comp;
326 Recursive::forEach(dy, [](
auto& v) { v = 0; });
328 Traversal::forEachLeafNode(this->subTreeCache(), [&](
auto const& node,
auto const& tp)
331 auto const& partial = localBasis.
partialsAt(local, comp);
334 auto re = Dune::Functions::flatVectorView(nodeToRangeMap_(node, tp, dy));
336 for (std::size_t i = 0; i < localBasis.
size(); ++i) {
338 auto c = Dune::Functions::flatVectorView(localCoefficients_[node.localIndex(i)]);
341 auto d_comp = Dune::Functions::flatVectorView(partial[i]);
343 std::size_t dimC = c.size();
344 std::size_t dimV = d_comp.size();
345 assert(dimC*dimV == std::size_t(re.size()));
346 for(std::size_t j = 0; j < dimC; ++j) {
348 for(std::size_t k = 0; k < dimV; ++k)
349 re[j*dimV + k] += c_j*d_comp[k];
LocalFunction(std::shared_ptr< LV > localView, TP const &treePath, C const &coefficients, Type type)
Constructor. Stores a copy of the DiscreteFunction.
Definition: DiscreteLocalFunction.inc.hpp:80
constexpr bool MultiIndex
A multi-index type.
Definition: Concepts.hpp:150
Convert a simple (scalar) local basis into a global basis.
Definition: LocalToGlobalAdapter.hpp:64
Definition: FieldMatVec.hpp:12
AMDiS::LocalView< Self > LocalView
Type of the local view on the restriction of the basis to a single element.
Definition: GlobalBasis.hpp:67
Definition: AdaptBase.hpp:6
A mutable view on the subspace of a DOFVector,.
Definition: DiscreteFunction.hpp:36
std::size_t size() const
Return the number of local basis functions.
Definition: LocalToGlobalAdapter.hpp:96
A simple node to range map using the nested tree indices.
Definition: HierarchicNodeToRangeMap.hpp:23
auto const & partialsAt(typename Traits::DomainLocal const &x, std::size_t comp) const
Definition: LocalToGlobalAdapter.hpp:176
LocalFunction< DerType > makeDerivative(DerType type) const
Create a LocalFunction representing the derivative.
Definition: DiscreteLocalFunction.inc.hpp:127
void bind(Element const &element)
Bind the LocalView to the element.
Definition: DiscreteLocalFunction.inc.hpp:88
Definition: DerivativeTraits.hpp:29
void unbind()
Unbind the LocalView from the element.
Definition: DiscreteLocalFunction.inc.hpp:97
auto order() const -> decltype(AMDiS::order(std::declval< SubTree >()))
The polynomial degree of the LocalFunctions basis-functions.
Definition: DiscreteLocalFunction.inc.hpp:134
Element const & localContext() const
Return the bound element.
Definition: DiscreteLocalFunction.inc.hpp:142
Definition: DiscreteLocalFunction.inc.hpp:57
auto const & gradientsAt(typename Traits::DomainLocal const &x) const
Definition: LocalToGlobalAdapter.hpp:147