Dune-Fufem 2.12-git
Loading...
Searching...
No Matches
traversal.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_BACKENDS_TRAVERSAL_HH
8#define DUNE_FUFEM_BACKENDS_TRAVERSAL_HH
9
10#include <type_traits>
11#include <utility>
12#include <functional>
13#include <variant>
14#include <tuple>
15
19
21
23
25
26
27
28namespace Dune::Fufem::Impl {
29
30 // Shallow traversal implementation
31
32 template<class Vector, class F>
33 static void forEachVectorEntry(Vector&& vector, F&& f)
34 {
36 f(vector[i], i);
37 });
38 }
39
40 template<class Matrix, class F>
41 static void forEachMatrixEntry(Matrix&& matrix, F&& f)
42 {
43 for(auto i : Dune::range(matrix.N()))
44 for(auto&& [matrix_ij, j] : Dune::sparseRange(matrix[i]))
45 f(matrix_ij, i, j);
46 }
47
48 template<class... MatrixRows, class F>
49 static void forEachMatrixEntry(const Dune::MultiTypeBlockMatrix<MatrixRows...>& matrix, F&& f)
50 {
51 using Matrix = Dune::MultiTypeBlockMatrix<MatrixRows...>;
54 f(matrix[i][j], i, j);
55 });
56 });
57 }
58
59 template<class... MatrixRows, class F>
60 static void forEachMatrixEntry(Dune::MultiTypeBlockMatrix<MatrixRows...>& matrix, F&& f)
61 {
62 using Matrix = Dune::MultiTypeBlockMatrix<MatrixRows...>;
65 f(matrix[i][j], i, j);
66 });
67 });
68 }
69
70 template<class Matrix, class F>
71 static void forEachMatrixEntry(const Dune::Assembler::SingleRowMatrix<Matrix>& matrix, F&& f)
72 {
73 for(auto&& [matrix_0j, j] : Dune::sparseRange(matrix[0]))
74 f(matrix_0j, std::monostate(), j);
75 }
76
77 template<class Matrix, class F>
78 static void forEachMatrixEntry(Dune::Assembler::SingleRowMatrix<Matrix>& matrix, F&& f)
79 {
80 for(auto&& [matrix_0j, j] : Dune::sparseRange(matrix[0]))
81 f(matrix_0j, std::monostate(), j);
82 }
83
84 template<class Matrix, class F>
85 static void forEachMatrixEntry(const Dune::Assembler::SingleColumnMatrix<Matrix>& matrix, F&& f)
86 {
87 for(auto i : Dune::range(matrix.N()))
88 for(auto&& [matrix_i0, j] : Dune::sparseRange(matrix[i]))
89 f(matrix_i0, i, std::monostate());
90 }
91
92 template<class Matrix, class F>
93 static void forEachMatrixEntry(Dune::Assembler::SingleColumnMatrix<Matrix>& matrix, F&& f)
94 {
95 for(auto i : Dune::range(matrix.N()))
96 for(auto&& [matrix_i0, j] : Dune::sparseRange(matrix[i]))
97 f(matrix_i0, i, std::monostate());
98 }
99
100 // Utilities for deep traversal
101
102 template<class size_type, std::size_t n, class Tail>
103 auto extendMultiIndex(const Dune::Functions::StaticMultiIndex<size_type, n>& head, Tail tail)
104 {
106 return head;
107 else
108 return std::apply([&](const auto&... headEntries) {
110 }, static_cast<const std::array<size_type,n>&>(head));
111 }
112
113 template<class F, class MultiIndex>
114 class RecursiveVectorVisitor
115 {
116 public:
117
118 RecursiveVectorVisitor(F f, MultiIndex index)
119 : f_(f)
120 , index_(index)
121 {}
122
123 template<class Entry, class FlatIndex>
124 void operator()(Entry&& vector_i, FlatIndex i)
125 {
127 f_(vector_i, extendMultiIndex(index_, i));
128 else
129 Impl::forEachVectorEntry(vector_i, Dune::Fufem::Impl::RecursiveVectorVisitor(f_, extendMultiIndex(index_, i)));
130 }
131
132 private:
133 F f_;
134 const MultiIndex index_;
135 };
136
137
138 template<class F, class RowMultiIndex, class ColMultiIndex>
139 class RecursiveMatrixVisitor
140 {
141 public:
142
143 RecursiveMatrixVisitor(F f, RowMultiIndex rowIndex, ColMultiIndex colIndex)
144 : f_(f)
145 , rowIndex_(rowIndex)
146 , colIndex_(colIndex)
147 {}
148
149 template<class Entry, class FlatRowIndex, class FlatColIndex>
150 void operator()(Entry&& matrix_ij, FlatRowIndex i, FlatColIndex j)
151 {
153 f_(matrix_ij, extendMultiIndex(rowIndex_, i), extendMultiIndex(colIndex_, j));
154 else
155 Impl::forEachMatrixEntry(matrix_ij, Dune::Fufem::Impl::RecursiveMatrixVisitor(f_, extendMultiIndex(rowIndex_, i), extendMultiIndex(colIndex_, j)));
156 }
157
158 private:
159 F f_;
160 const RowMultiIndex rowIndex_;
161 const RowMultiIndex colIndex_;
162 };
163
164
165} // namespace Dune::Fufem::Impl
166
167
168
169namespace Dune::Fufem {
170
179 template<class Vector, class F>
180 static void forEachVectorEntry(Vector&& vector, F&& f)
181 {
182 Impl::forEachVectorEntry(vector, f);
183 }
184
193 template<class Matrix, class F>
194 static void forEachMatrixEntry(Matrix&& matrix, F&& f)
195 {
196 Impl::forEachMatrixEntry(matrix, f);
197 }
198
211 template<class Vector, class F>
212 static void recursiveForEachVectorEntry(Vector&& vector, F&& f)
213 {
215 auto recursive_f = Dune::Fufem::Impl::RecursiveVectorVisitor(std::ref(f), EmptyIndex{});
216 Impl::forEachVectorEntry(vector, recursive_f);
217 }
218
231 template<class Matrix, class F>
232 static void recursiveForEachMatrixEntry(Matrix&& matrix, F&& f)
233 {
235 auto recursive_f = Dune::Fufem::Impl::RecursiveMatrixVisitor(std::ref(f), EmptyIndex{}, EmptyIndex{});
236 Impl::forEachMatrixEntry(matrix, recursive_f);
237 }
238
239} // namespace Dune::Fufem
240
241
242
243#endif // DUNE_FUFEM_BACKENDS_TRAVERSAL_HH
Dune::BCRSMatrix< FieldMatrix< T, n, m >, TA > Matrix
OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator matrix
auto sparseRange(Range &&range)
static constexpr IntegralRange< T > range(T from, T to) noexcept
constexpr auto size(const T &t)
constexpr void forEach(Range &&range, F &&f)
static constexpr size_type N()
size_type rowIndex() const
std::ptrdiff_t index() const
virtual void operator()()=0
constexpr std::integer_sequence< T, II... > tail(std::integer_sequence< T, I0, II... >)
constexpr std::integral_constant< T, I0 > head(std::integer_sequence< T, I0, II... >)
size_type M() const
size_type N() const
T apply(T... args)
T forward(T... args)
Definition dunefunctionsboundaryfunctionalassembler.hh:29
STL namespace.
T ref(T... args)