Loading...
Searching...
No Matches
operator.hpp
Go to the documentation of this file.
1#pragma once
2#include "linalg.hpp"
3#include "vector.hpp"
4
5namespace terra::linalg {
6
7/// @brief Modes for applying an operator to a vector.
8///
9/// @note It is important to pair the modes correctly.
10/// **If unsure, use temporary vectors, apply each operator individually (typically defaulting to modes 'Replace'
11/// and 'CommunicateAdditively'), and add the results in the end.**
12///
13/// Elementwise operators have to communicate after all local values have been updated.
14/// The general approach is to communicate and sum up values of overlapping nodes.
15/// If the 'ApplyMode' is set to 'Add' and additive communication follows that, then also previous values will
16/// be included in the sum.
17///
18/// The modes are, for instance, useful for block matrices like the Stokes operator.
19/// If you want to execute, e.g., \f$ y \gets Au + B^T p \f$ then you could execute this as follows:
20/// \f[
21/// \begin{aligned}
22/// y &\gets Au && \qquad \text{replace and skip communication} \\
23/// y &\gets y + B^Tp && \qquad \text{add and communicate additively} \\
24/// \end{aligned}
25/// \f]
26/// Note that if communication is not skipped in the first step in this example, the subdomain boundary data will be
27/// wrong.
28///
30{
31 Replace, ///< Overwrite the destination vector.
32 Add, ///< Add to the destination vector.
33};
34
35/// @brief Modes for communication during operator application.
36///
37/// @note See @ref OperatorApplyMode for more details.
38///
40{
41 SkipCommunication, ///< Do not communicate.
42 CommunicateAdditively, ///< Communicate and add results.
43};
44
45/// @brief Modes for applying stored matrices.
47{
48 Off, ///< Do not use stored matrices.
49 Full, ///< Use stored matrices on all elements.
50 Selective, ///< Use stored matrices on selected, marked elements only, assemble on all others.
51};
52
53/// @brief Concept for types that behave like linear operators.
54///
55/// Requires vector types, matvec implementation, and compatibility with VectorLike.
56template < typename T >
57concept OperatorLike = requires(
58 const T& self_const,
59 T& self,
60 const typename T::SrcVectorType& src,
61 typename T::DstVectorType& dst,
62 dense::Vec< int, 2 > block ) {
63 // Requires exposing the vector types.
64 typename T::SrcVectorType;
65 typename T::DstVectorType;
66
67 // Require that Src and Dst vector types satisfy VectorLike
70
71 // Required matvec implementation
72 // TODO: T& self is not const because having apply_impl const is not convenient - mostly because
73 // it is handy to reuse send/recv buffers that are members of an operator implementation.
74 // To modify these members (i.e., to communicate) we cannot be const :(
75 { self.apply_impl( src, dst ) } -> std::same_as< void >;
76};
77
78/// @brief Concept for types that can be used as Galerkin coarse-grid operators in a multigrid hierarchy.
79/// See galerkin_coarsening_linear.hpp for more information on GCA.
80template < typename Op >
81concept GCACapable = requires(
82 // dummy variables to define requirements
83 const Op& self_const,
84 const int local_subdomain_id,
85 const int x_cell,
86 const int y_cell,
87 const int r_cell,
88 // 0 or 1 wedge within the hex cell on which GCA operates
89 const int wedge,
90 const dense::Mat< typename Op::ScalarType, Op::LocalMatrixDim, Op::LocalMatrixDim >& mat ) {
91 // Require that the argument to be a linear operator
92 requires OperatorLike< Op >;
93
94 // The operator must show the dimensions of the local matrix (might be 18 for vectorial diffusion ops in 3D like EpsilonDivDiv,
95 // or 6 for a simple scalar div-k-grad)
96 { Op::LocalMatrixDim } -> std::convertible_to< int >;
97
98 // The operator must allow read/write access to his local matrices in order to GCA them.
99 // It is indeed weird that the write access set_local_matrix() shall be const.
100 // However, the View access implementation of Kokkos and the requirement of kernels being const
101 // make this possible and necessary.
102 {
103 self_const.get_local_matrix( local_subdomain_id, x_cell, y_cell, r_cell, wedge )
104 } -> std::same_as< dense::Mat< typename Op::ScalarType, Op::LocalMatrixDim, Op::LocalMatrixDim > >;
105
106 { self_const.set_local_matrix( local_subdomain_id, x_cell, y_cell, r_cell, wedge, mat ) } -> std::same_as< void >;
107
108 // Since TwoGridGCA works with multiple operators, and their respective domains (coarse-fine nested loop),
109 // it is required to have access to geometric information stored in the operators.
110 { self_const.get_domain() } -> std::same_as< const grid::shell::DistributedDomain& >;
111 { self_const.get_radii() } -> std::same_as< grid::Grid2DDataScalar< typename Op::ScalarType > >;
112};
113
114/// @brief Concept for types that behave like block 2x2 operators.
115/// Extends OperatorLike and requires block types and accessors.
116template < typename T >
117concept Block2x2OperatorLike = OperatorLike< T > && requires( const T& self_const, T& self ) {
118 // Require that Src and Dst vector types satisfy VectorLike
121
122 typename T::Block11Type;
123 typename T::Block12Type;
124 typename T::Block21Type;
125 typename T::Block22Type;
126
131
132 { self_const.block_11() } -> std::same_as< const typename T::Block11Type& >;
133 { self_const.block_12() } -> std::same_as< const typename T::Block12Type& >;
134 { self_const.block_21() } -> std::same_as< const typename T::Block21Type& >;
135 { self_const.block_22() } -> std::same_as< const typename T::Block22Type& >;
136
137 { self.block_11() } -> std::same_as< typename T::Block11Type& >;
138 { self.block_12() } -> std::same_as< typename T::Block12Type& >;
139 { self.block_21() } -> std::same_as< typename T::Block21Type& >;
140 { self.block_22() } -> std::same_as< typename T::Block22Type& >;
141};
142
143/// @brief Alias for the source vector type of an operator.
144template < OperatorLike Operator >
145using SrcOf = Operator::SrcVectorType;
146
147/// @brief Alias for the destination vector type of an operator.
148template < OperatorLike Operator >
149using DstOf = Operator::DstVectorType;
150
151/// @brief Apply an operator to a source vector and write to a destination vector.
152/// @param A Operator to apply.
153/// @param src Source vector.
154/// @param dst Destination vector.
155template < OperatorLike Operator >
156void apply( Operator& A, const SrcOf< Operator >& src, DstOf< Operator >& dst )
157{
158 A.apply_impl( src, dst );
159}
160
161namespace detail {
162
163/// @brief Dummy operator for testing concepts.
164/// Implements apply_impl as a no-op.
165template < VectorLike SrcVectorT, VectorLike DstVectorT >
167{
168 public:
169 using SrcVectorType = SrcVectorT;
170 using DstVectorType = DstVectorT;
171
172 /// @brief Dummy apply_impl, does nothing.
173 /// @param src Source vector.
174 /// @param dst Destination vector.
175 void apply_impl( const SrcVectorType& src, DstVectorType& dst ) const
176 {
177 (void) src;
178 (void) dst;
179 }
180};
181
182/// @brief Dummy concrete operator for concept checks.
183/// Uses DummyVector as vector types.
185{
186 public:
189
190 /// @brief Dummy apply_impl, does nothing.
191 /// @param src Source vector.
192 /// @param dst Destination vector.
193 void apply_impl( const SrcVectorType& src, DstVectorType& dst ) const
194 {
195 (void) src;
196 (void) dst;
197 }
198};
199
200/// @brief Dummy block 2x2 operator for concept checks.
201/// Contains four DummyConcreteOperator blocks.
203{
204 public:
207
212
213 /// @brief Dummy apply_impl, does nothing.
214 /// @param src Source block vector.
215 /// @param dst Destination block vector.
216 void apply_impl( const SrcVectorType& src, DstVectorType& dst ) const
217 {
218 (void) src;
219 (void) dst;
220 }
221
222 /// @brief Get const reference to block 11.
223 const Block11Type& block_11() const { return block_11_; }
224 /// @brief Get const reference to block 12.
225 const Block12Type& block_12() const { return block_12_; }
226 /// @brief Get const reference to block 21.
227 const Block21Type& block_21() const { return block_21_; }
228 /// @brief Get const reference to block 22.
229 const Block22Type& block_22() const { return block_22_; }
230
231 /// @brief Get mutable reference to block 11.
232 Block11Type& block_11() { return block_11_; }
233 /// @brief Get mutable reference to block 12.
234 Block12Type& block_12() { return block_12_; }
235 /// @brief Get mutable reference to block 21.
236 Block21Type& block_21() { return block_21_; }
237 /// @brief Get mutable reference to block 22.
238 Block22Type& block_22() { return block_22_; }
239
240 private:
241 Block11Type block_11_;
242 Block12Type block_12_;
243 Block21Type block_21_;
244 Block22Type block_22_;
245};
246
247/// @brief Static assertions to check concepts for dummy operators.
248static_assert( OperatorLike< DummyOperator< DummyVector< double >, DummyVector< double > > > );
251
252} // namespace detail
253
254} // namespace terra::linalg
Dummy block 2-vector class for concept checks and testing. Contains two DummyVector blocks.
Definition vector.hpp:253
Dummy block 2x2 operator for concept checks. Contains four DummyConcreteOperator blocks.
Definition operator.hpp:203
Block12Type & block_12()
Get mutable reference to block 12.
Definition operator.hpp:234
DummyConcreteOperator Block21Type
Definition operator.hpp:210
DummyConcreteOperator Block22Type
Definition operator.hpp:211
const Block22Type & block_22() const
Get const reference to block 22.
Definition operator.hpp:229
Block22Type & block_22()
Get mutable reference to block 22.
Definition operator.hpp:238
DummyConcreteOperator Block12Type
Definition operator.hpp:209
const Block21Type & block_21() const
Get const reference to block 21.
Definition operator.hpp:227
const Block11Type & block_11() const
Get const reference to block 11.
Definition operator.hpp:223
void apply_impl(const SrcVectorType &src, DstVectorType &dst) const
Dummy apply_impl, does nothing.
Definition operator.hpp:216
Block11Type & block_11()
Get mutable reference to block 11.
Definition operator.hpp:232
const Block12Type & block_12() const
Get const reference to block 12.
Definition operator.hpp:225
DummyConcreteOperator Block11Type
Definition operator.hpp:208
Block21Type & block_21()
Get mutable reference to block 21.
Definition operator.hpp:236
Dummy concrete operator for concept checks. Uses DummyVector as vector types.
Definition operator.hpp:185
void apply_impl(const SrcVectorType &src, DstVectorType &dst) const
Dummy apply_impl, does nothing.
Definition operator.hpp:193
Dummy operator for testing concepts. Implements apply_impl as a no-op.
Definition operator.hpp:167
DstVectorT DstVectorType
Definition operator.hpp:170
void apply_impl(const SrcVectorType &src, DstVectorType &dst) const
Dummy apply_impl, does nothing.
Definition operator.hpp:175
SrcVectorT SrcVectorType
Definition operator.hpp:169
Dummy vector class for concept checks and testing. Implements required vector operations as no-ops.
Definition vector.hpp:210
Concept for types that behave like block 2-vectors. Extends VectorLike and requires block types and a...
Definition vector.hpp:47
Concept for types that behave like block 2x2 operators. Extends OperatorLike and requires block types...
Definition operator.hpp:117
Concept for types that can be used as Galerkin coarse-grid operators in a multigrid hierarchy....
Definition operator.hpp:81
Concept for types that behave like linear operators.
Definition operator.hpp:57
Concept for types that behave like vectors. Requires exposing ScalarType and implementations for line...
Definition vector.hpp:8
Contains linear algebra utilities and functions for the Terra project.
Definition diagonally_scaled_operator.hpp:8
Operator::SrcVectorType SrcOf
Alias for the source vector type of an operator.
Definition operator.hpp:145
OperatorApplyMode
Modes for applying an operator to a vector.
Definition operator.hpp:30
@ Replace
Overwrite the destination vector.
@ Add
Add to the destination vector.
OperatorStoredMatrixMode
Modes for applying stored matrices.
Definition operator.hpp:47
@ Selective
Use stored matrices on selected, marked elements only, assemble on all others.
@ Full
Use stored matrices on all elements.
@ Off
Do not use stored matrices.
void apply(LinearForm &L, typename LinearForm::DstVectorType &dst)
Apply a linear form and write to a destination vector.
Definition linear_form.hpp:37
Operator::DstVectorType DstOf
Alias for the destination vector type of an operator.
Definition operator.hpp:149
OperatorCommunicationMode
Modes for communication during operator application.
Definition operator.hpp:40
@ CommunicateAdditively
Communicate and add results.