Dune-Fufem 2.11-git
Loading...
Searching...
No Matches
localinterpolationconstraints.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_CONSTRAINTS_LOCALINTERPOLATIONCONSTRAINTS_HH
8#define DUNE_FUFEM_CONSTRAINTS_LOCALINTERPOLATIONCONSTRAINTS_HH
9
10#include <cmath>
11#include <type_traits>
12#include <vector>
13
16
17#if DUNE_VERSION_GTE(DUNE_FUNCTIONS, 2, 11)
20#else
21#include <dune/typetree/traversal.hh>
22#include <dune/typetree/childextraction.hh>
23#endif
24
26
27
28
29namespace Dune::Fufem {
30
31
32
60template<class PrimaryLocalView, class SecondaryLocalView, class SecondaryToPrimary, class SecondaryDOFs, class Constraints>
61void computeLocalInterpolationConstraints(const PrimaryLocalView& primaryLocalView, const SecondaryLocalView& secondaryLocalView, const SecondaryToPrimary& localSecondaryToPrimary, const SecondaryDOFs& secondaryDOFs, Constraints& constraints)
62{
63 using Coefficient = typename Constraints::Coefficient;
64
65 auto&& isInterpolated = Dune::Functions::istlVectorBackend(constraints.isConstrained());
66 auto&& interpolation = constraints.linearTerm();
67
68 // Interpolation weights smaller than the tolerance will be ignored
69 const auto tol = 1e-5;
70
71 auto localIsConstrained = std::vector<bool>();
72 auto interpolationValues = std::vector<Coefficient>();
73
74 Dune::TypeTree::forEachLeafNode(secondaryLocalView.tree(), [&](auto&& secondaryNode, auto&& treePath) {
75 auto&& primaryNode = Dune::TypeTree::child(primaryLocalView.tree(), treePath);
76 if ((primaryNode.size() == 0) or (secondaryNode.size() == 0))
77 return;
78
79 const auto& primaryBasis = primaryNode.finiteElement().localBasis();
80 using Range = typename std::decay_t<decltype(primaryBasis)>::Traits::RangeType;
81
82 interpolationValues.resize(secondaryNode.finiteElement().size());
83 localIsConstrained.clear();
84 localIsConstrained.resize(secondaryNode.finiteElement().size(), false);
85
86 // We first compute the primary basis values at all interpolation points.
87 auto primaryBasisValues = std::vector<std::vector<Range>>(primaryBasis.size());
88 auto k = 0;
89 auto trackingBasisFunction = [&](const auto& xLocalSecondary) {
90 primaryBasisValues.resize(k+1);
91 auto xLocalPrimary = localSecondaryToPrimary(xLocalSecondary);
92 primaryBasis.evaluateFunction(xLocalPrimary, primaryBasisValues[k]);
93 return primaryBasisValues[k++][0];
94 };
95 secondaryNode.finiteElement().localInterpolation().interpolate(trackingBasisFunction, interpolationValues);
96
97 // Node we interpolate any primary basis function on the current secondary element
98 for(auto j : Dune::range(primaryBasis.size()))
99 {
100 auto j_global = primaryLocalView.index(primaryNode.localIndex(j));
101
102 // primaryBasisFunction_j behaves like the j-th primary bases function if
103 // interpolate() evaluates it at the same points in the same
104 // order as above.
105 auto k = 0;
106 auto primaryBasisFunction_j = [&](const auto& x) {
107 return primaryBasisValues[k++][j];
108 };
109 secondaryNode.finiteElement().localInterpolation().interpolate(primaryBasisFunction_j, interpolationValues);
110
111 for(auto i : Dune::range(secondaryNode.finiteElement().size()))
112 {
113 // Only basis functions from the given set are considered
114 // for being interpolated from the primary basis.
115 if (not(secondaryDOFs.contains(secondaryNode.localIndex(i))))
116 continue;
117
118 auto i_global = secondaryLocalView.index(secondaryNode.localIndex(i));
119
120 // We need to skip this if dof is already constrained.
121 // Otherwise we may add interpolation weights from multiple elements
122 // resulting in doubled interpolation weights after resolving the dependencies.
123 if (isInterpolated[i_global])
124 continue;
125
126 if (i_global != j_global)
127 if (std::abs(interpolationValues[i]) > tol)
128 {
129 interpolation[i_global][j_global] = interpolationValues[i];
130 localIsConstrained[i] = true;
131 }
132 }
133 }
134 // Now mark all newly constrained nodes
135 for(auto i : Dune::range(secondaryNode.finiteElement().size()))
136 if (localIsConstrained[i])
137 isInterpolated[secondaryLocalView.index(secondaryNode.localIndex(i))] = true;
138 });
139}
140
141
142
143
144} // namespace Dune::Fufem
145
146
147
148#endif // DUNE_FUFEM_CONSTRAINTS_LOCALINTERPOLATIONCONSTRAINTS_HH
auto istlVectorBackend(Vector &v)
static constexpr IntegralRange< std::decay_t< T > > range(T &&from, U &&to) noexcept
void forEachLeafNode(Tree &&tree, LeafFunc &&leafFunc)
void computeLocalInterpolationConstraints(const PrimaryLocalView &primaryLocalView, const SecondaryLocalView &secondaryLocalView, const SecondaryToPrimary &localSecondaryToPrimary, const SecondaryDOFs &secondaryDOFs, Constraints &constraints)
Compute local constraints from interpolating between local views.
Definition localinterpolationconstraints.hh:61
Definition dunefunctionsboundaryfunctionalassembler.hh:29
T forward(T... args)