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