include/meltpooldg/linear_algebra/utilities_matrixfree.hpp Source File

Developer Documentation: include/meltpooldg/linear_algebra/utilities_matrixfree.hpp Source File
Developer Documentation
utilities_matrixfree.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <deal.II/lac/generic_linear_algebra.h>
4
5#include <deal.II/matrix_free/matrix_free.h>
6#include <deal.II/matrix_free/operators.h>
7
11
13{
14 template <typename number = double>
15 using VectorType = dealii::LinearAlgebra::distributed::Vector<number>;
16 template <typename number = double>
17 using BlockVectorType = dealii::LinearAlgebra::distributed::BlockVector<number>;
33 template <int dim,
34 typename number = double,
35 typename DoFVectorType = VectorType<number>,
36 typename SrcRhsVectorType = VectorType<number>,
37 typename std::enable_if_t<std::is_same_v<DoFVectorType, VectorType<number>>, int> = 0>
38 inline void
41 DoFVectorType &rhs,
42 const SrcRhsVectorType &src,
43 const ScratchData<dim, dim, number> &scratch_data,
44 const unsigned int dof_idx,
45 const unsigned int dof_no_bc_idx,
46 const bool zero_out,
47 const std::optional<std::pair<std::vector<unsigned int>, std::vector<number>>>
48 &additional_inhomogeneous_constraints = std::nullopt)
49 {
50 // The dof index that is used for the DoF Vector from the matrix-vector
51 // product must be switched to the one without Dirichlet boundary
52 // conditions, such that inhomogeneities are not zeroed out during
53 // read_dof_values().
54 operator_base.reset_dof_index(dof_no_bc_idx);
55
56 DoFVectorType temp_rhs;
57 scratch_data.initialize_dof_vector(temp_rhs, dof_no_bc_idx);
58
59 DoFVectorType bc_values;
60 scratch_data.initialize_dof_vector(bc_values, dof_no_bc_idx);
61
62 // set inhomogeneity
63 if (additional_inhomogeneous_constraints)
64 {
65 const auto &bc = *additional_inhomogeneous_constraints;
66 for (unsigned int i = 0; i < bc.first.size(); ++i)
67 bc_values.local_element(bc.first[i]) = bc.second[i];
68 }
69
70 scratch_data.get_constraint(dof_idx).distribute(bc_values);
71
72 // perform matrix-vector multiplication (with unconstrained system and constrained set in
73 // Vector)
74 operator_base.vmult(temp_rhs, bc_values);
75
76 // Modify right-hand side
77 temp_rhs *= -1.0;
78 operator_base.create_rhs(temp_rhs, src);
79 /*
80 * Zero-out constrained values
81 */
82 if (zero_out)
83 rhs = temp_rhs;
84 else
85 rhs += temp_rhs;
86
87 // zero-out values of additional inhomogeneity
88 if (additional_inhomogeneous_constraints)
89 {
90 const auto &bc = *additional_inhomogeneous_constraints;
91 for (const auto &i : bc.first)
92 {
93 rhs.local_element(i) = 0;
94 }
95 }
96
97 scratch_data.get_constraint(dof_idx).set_zero(rhs);
98
99 operator_base.reset_dof_index(dof_idx);
100 }
101
123 template <
124 int dim,
125 typename number = double,
126 typename DoFVectorType = BlockVectorType<number>,
127 typename SrcRhsVectorType = VectorType<number>,
128 typename std::enable_if_t<std::is_same_v<DoFVectorType, BlockVectorType<number>>, int> = 0>
129 inline void
131 OperatorMatrixFree<dim, number> &operator_base,
132 DoFVectorType &rhs,
133 const SrcRhsVectorType &src,
134 const ScratchData<dim, dim, number> &scratch_data,
135 const std::array<unsigned int, dim> &dof_indices_per_block,
136 const unsigned int &dof_no_bc_idx,
137 const bool zero_out,
138 const std::optional<std::pair<std::vector<unsigned int>, std::vector<std::vector<number>>>>
139 &additional_inhomogeneous_constraints = std::nullopt)
140 {
141 // The dof index that is used for the DoF Vector from the matrix-vector
142 // product must be switched to the one without Dirichlet boundary
143 // conditions, such that inhomogeneities are not zeroed out during
144 // read_dof_values().
145 operator_base.reset_dof_index(dof_no_bc_idx);
146
147 DoFVectorType temp_rhs;
148 scratch_data.initialize_dof_vector(temp_rhs, dof_no_bc_idx);
149
150 DoFVectorType bc_values;
151 scratch_data.initialize_dof_vector(bc_values, dof_no_bc_idx);
152
153 for (unsigned int d = 0; d < dim; ++d)
154 {
155 auto &bc_values_d = bc_values.block(d);
156
157 // set inhomogeneity
158 if (additional_inhomogeneous_constraints)
159 {
160 const auto &bc = *additional_inhomogeneous_constraints;
161 for (unsigned int i = 0; i < bc.first.size(); ++i)
162 {
163 bc_values_d.local_element(bc.first[i]) = bc.second[d][i];
164 }
165 }
166 scratch_data.get_constraint(dof_indices_per_block[d]).distribute(bc_values_d);
167 }
168
169 // perform matrix-vector multiplication (with unconstrained system and constrained set in
170 // Vector)
171 operator_base.vmult(temp_rhs, bc_values);
172
173 // Modify right-hand side
174 temp_rhs *= -1.0;
175 operator_base.create_rhs(temp_rhs, src);
176 /*
177 * Zero-out constrained values
178 */
179 if (zero_out)
180 rhs = temp_rhs;
181 else
182 rhs += temp_rhs;
183
184 for (unsigned int d = 0; d < dim; ++d)
185 {
186 auto &rhs_d = rhs.block(d);
187
188 // zero-out values of additional inhomogeneity
189 if (additional_inhomogeneous_constraints)
190 {
191 const auto &bc = *additional_inhomogeneous_constraints;
192 for (const auto &i : bc.first)
193 {
194 rhs_d.local_element(i) = 0;
195 }
196 }
197
198 scratch_data.get_constraint(dof_indices_per_block[d]).set_zero(rhs_d);
199 }
200
201 operator_base.reset_dof_index(dof_indices_per_block[0]);
202 }
203
214 template <int dim, int n_components, typename number>
215 void
216 local_apply_inverse_mass_matrix(const dealii::MatrixFree<dim, number> &matrix_free,
218 const VectorType<number> &src,
219 const std::pair<unsigned int, unsigned int> &cell_range,
220 const unsigned int dof_idx,
221 const unsigned int quad_idx)
222 {
223 FECellIntegrator<dim, n_components, number> phi(matrix_free, dof_idx, quad_idx);
224 dealii::MatrixFreeOperators::CellwiseInverseMassMatrix<dim, -1, n_components, number> inverse(
225 phi);
226
227 for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
228 {
229 phi.reinit(cell);
230 phi.read_dof_values(src);
231 inverse.apply(phi.begin_dof_values(), phi.begin_dof_values());
232 phi.set_dof_values(dst);
233 }
234 }
235} // namespace MeltPoolDG::Utilities::MatrixFree
void reset_dof_index(const unsigned int dof_idx_in)
Set the index for the current degrees of freedom (DoF).
Definition operator_base.hpp:32
Operator handling matrix-free computations.
Definition operator_base.hpp:190
virtual void create_rhs(VectorType &, const VectorType &) const
Compute the right-hand side vector.
Definition operator_base.hpp:208
virtual void vmult(VectorType &, const VectorType &) const
Definition operator_base.hpp:239
Container for shared scratch data between operations/operators.
Definition scratch_data.hpp:61
void initialize_dof_vector(VectorType &vec, const unsigned int dof_idx) const
Initialize a distributed vector for a given DoF index.
Definition scratch_data.cpp:272
const dealii::AffineConstraints< number > & get_constraint(const unsigned int constraint_index) const
Get a constraint object by index (const overload).
Definition scratch_data.cpp:375
Definition utilities_matrixfree.hpp:13
dealii::LinearAlgebra::distributed::BlockVector< number > BlockVectorType
Definition utilities_matrixfree.hpp:17
void create_rhs_and_apply_dirichlet_matrixfree(OperatorMatrixFree< dim, number > &operator_base, DoFVectorType &rhs, const SrcRhsVectorType &src, const ScratchData< dim, dim, number > &scratch_data, const unsigned int dof_idx, const unsigned int dof_no_bc_idx, const bool zero_out, const std::optional< std::pair< std::vector< unsigned int >, std::vector< number > > > &additional_inhomogeneous_constraints=std::nullopt)
Definition utilities_matrixfree.hpp:39
dealii::LinearAlgebra::distributed::Vector< number > VectorType
Definition utilities_matrixfree.hpp:15
void local_apply_inverse_mass_matrix(const dealii::MatrixFree< dim, number > &matrix_free, VectorType< number > &dst, const VectorType< number > &src, const std::pair< unsigned int, unsigned int > &cell_range, const unsigned int dof_idx, const unsigned int quad_idx)
Definition utilities_matrixfree.hpp:216
dealii::FEEvaluation< dim, -1, 0, n_components, number, VectorizedArrayType > FECellIntegrator
Definition fe_integrator.hpp:14