Dune-Fufem 2.11-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
18
20
21#include <dune/assembler/backends/singlerowcolmatrix.hh>
22
24
25
26
27namespace Dune::Fufem::Impl {
28
29 // Shallow traversal implementation
30
31 template<class Vector, class F>
32 static void forEachVectorEntry(Vector&& vector, F&& f)
33 {
35 f(vector[i], i);
36 });
37 }
38
39 template<class Matrix, class F>
40 static void forEachMatrixEntry(Matrix&& matrix, F&& f)
41 {
42 for(auto i : Dune::range(matrix.N()))
43 for(auto&& [matrix_ij, j] : Dune::sparseRange(matrix[i]))
44 f(matrix_ij, i, j);
45 }
46
47 template<class... MatrixRows, class F>
48 static void forEachMatrixEntry(const Dune::MultiTypeBlockMatrix<MatrixRows...>& matrix, F&& f)
49 {
50 using Matrix = Dune::MultiTypeBlockMatrix<MatrixRows...>;
53 f(matrix[i][j], i, j);
54 });
55 });
56 }
57
58 template<class... MatrixRows, class F>
59 static void forEachMatrixEntry(Dune::MultiTypeBlockMatrix<MatrixRows...>& matrix, F&& f)
60 {
61 using Matrix = Dune::MultiTypeBlockMatrix<MatrixRows...>;
64 f(matrix[i][j], i, j);
65 });
66 });
67 }
68
69 template<class Matrix, class F>
70 static void forEachMatrixEntry(const Dune::Assembler::SingleRowMatrix<Matrix>& matrix, F&& f)
71 {
72 for(auto&& [matrix_0j, j] : Dune::sparseRange(matrix[0]))
73 f(matrix_0j, std::monostate(), j);
74 }
75
76 template<class Matrix, class F>
77 static void forEachMatrixEntry(Dune::Assembler::SingleRowMatrix<Matrix>& matrix, F&& f)
78 {
79 for(auto&& [matrix_0j, j] : Dune::sparseRange(matrix[0]))
80 f(matrix_0j, std::monostate(), j);
81 }
82
83 template<class Matrix, class F>
84 static void forEachMatrixEntry(const Dune::Assembler::SingleColumnMatrix<Matrix>& matrix, F&& f)
85 {
86 for(auto i : Dune::range(matrix.N()))
87 for(auto&& [matrix_i0, j] : Dune::sparseRange(matrix[i]))
88 f(matrix_i0, i, std::monostate());
89 }
90
91 template<class Matrix, class F>
92 static void forEachMatrixEntry(Dune::Assembler::SingleColumnMatrix<Matrix>& matrix, F&& f)
93 {
94 for(auto i : Dune::range(matrix.N()))
95 for(auto&& [matrix_i0, j] : Dune::sparseRange(matrix[i]))
96 f(matrix_i0, i, std::monostate());
97 }
98
99 // Utilities for deep traversal
100
101 template<class size_type, std::size_t n, class Tail>
102 auto extendMultiIndex(const Dune::Functions::StaticMultiIndex<size_type, n>& head, Tail tail)
103 {
105 return head;
106 else
107 return std::apply([&](const auto&... headEntries) {
109 }, head);
110 }
111
112 template<class F, class MultiIndex>
113 class RecursiveVectorVisitor
114 {
115 public:
116
117 RecursiveVectorVisitor(F f, MultiIndex index)
118 : f_(f)
119 , index_(index)
120 {}
121
122 template<class Entry, class FlatIndex>
123 void operator()(Entry&& vector_i, FlatIndex i)
124 {
126 f_(vector_i, extendMultiIndex(index_, i));
127 else
128 Impl::forEachVectorEntry(vector_i, Dune::Fufem::Impl::RecursiveVectorVisitor(f_, extendMultiIndex(index_, i)));
129 }
130
131 private:
132 F f_;
133 const MultiIndex index_;
134 };
135
136
137 template<class F, class RowMultiIndex, class ColMultiIndex>
138 class RecursiveMatrixVisitor
139 {
140 public:
141
142 RecursiveMatrixVisitor(F f, RowMultiIndex rowIndex, ColMultiIndex colIndex)
143 : f_(f)
144 , rowIndex_(rowIndex)
145 , colIndex_(colIndex)
146 {}
147
148 template<class Entry, class FlatRowIndex, class FlatColIndex>
149 void operator()(Entry&& matrix_ij, FlatRowIndex i, FlatColIndex j)
150 {
152 f_(matrix_ij, extendMultiIndex(rowIndex_, i), extendMultiIndex(colIndex_, j));
153 else
154 Impl::forEachMatrixEntry(matrix_ij, Dune::Fufem::Impl::RecursiveMatrixVisitor(f_, extendMultiIndex(rowIndex_, i), extendMultiIndex(colIndex_, j)));
155 }
156
157 private:
158 F f_;
159 const RowMultiIndex rowIndex_;
160 const RowMultiIndex colIndex_;
161 };
162
163
164} // namespace Dune::Fufem::Impl
165
166
167
168namespace Dune::Fufem {
169
178 template<class Vector, class F>
179 static void forEachVectorEntry(Vector&& vector, F&& f)
180 {
181 Impl::forEachVectorEntry(vector, f);
182 }
183
192 template<class Matrix, class F>
193 static void forEachMatrixEntry(Matrix&& matrix, F&& f)
194 {
195 Impl::forEachMatrixEntry(matrix, f);
196 }
197
210 template<class Vector, class F>
211 static void recursiveForEachVectorEntry(Vector&& vector, F&& f)
212 {
214 auto recursive_f = Dune::Fufem::Impl::RecursiveVectorVisitor(std::ref(f), EmptyIndex{});
215 Impl::forEachVectorEntry(vector, recursive_f);
216 }
217
230 template<class Matrix, class F>
231 static void recursiveForEachMatrixEntry(Matrix&& matrix, F&& f)
232 {
234 auto recursive_f = Dune::Fufem::Impl::RecursiveMatrixVisitor(std::ref(f), EmptyIndex{}, EmptyIndex{});
235 Impl::forEachMatrixEntry(matrix, recursive_f);
236 }
237
238} // namespace Dune::Fufem
239
240
241
242#endif // DUNE_FUFEM_BACKENDS_TRAVERSAL_HH
Dune::BCRSMatrix< FieldMatrix< T, n, m >, TA > Matrix
OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator matrix
static constexpr IntegralRange< std::decay_t< T > > range(T &&from, U &&to) noexcept
auto sparseRange(Range &&range)
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... >)
STL namespace.
Definition dunefunctionsboundaryfunctionalassembler.hh:29
size_type M() const
size_type N() const
T apply(T... args)
T forward(T... args)
T ref(T... args)