PRISMS-PF Manual
Loading...
Searching...
No Matches
invm_manager.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: © 2025 PRISMS Center at the University of Michigan
2// SPDX-License-Identifier: GNU Lesser General Public Version 2.1
3
4#pragma once
5
6#include <deal.II/base/vectorization.h>
7#include <deal.II/dofs/dof_handler.h>
8#include <deal.II/fe/fe_system.h>
9#include <deal.II/lac/affine_constraints.h>
10#include <deal.II/lac/la_parallel_vector.h>
11#include <deal.II/matrix_free/fe_evaluation.h>
12#include <deal.II/matrix_free/matrix_free.h>
13
18
19#include <prismspf/config.h>
20
22
26template <unsigned int dim, unsigned int degree, typename number>
28{
29public:
30 using ScalarValue = dealii::VectorizedArray<number>;
31 using VectorValue = dealii::Tensor<1, dim, ScalarValue>;
32
39 explicit InvMManager(const DoFManager<dim, degree> &dof_manager,
40 const ConstraintManager<dim, degree, number> &constraint_manager,
41 bool _calculate_scalar,
42 bool _calculate_vector)
43 : num_levels(dof_manager.get_dof_handlers_levels().size())
44 , calculate_scalar(_calculate_scalar)
45 , calculate_vector(_calculate_vector)
46 {
47 data.resize(num_levels);
48 jxw_scalar.resize(num_levels);
49 invm_scalar.resize(num_levels);
51 jxw_vector.resize(num_levels);
52 invm_vector.resize(num_levels);
54 reinit(dof_manager, constraint_manager);
55 }
56
57 void
58 reinit(const DoFManager<dim, degree> &dof_manager,
59 const ConstraintManager<dim, degree, number> &constraint_manager)
60 {
61 const std::vector<std::array<dealii::DoFHandler<dim>, 2>> &dof_handlers =
62 dof_manager.get_dof_handlers_levels();
63 const std::vector<std::array<dealii::AffineConstraints<number>, 2>> &constraints =
64 constraint_manager.get_generic_constraints_levels();
65 for (unsigned int i = 0; i < data.size(); ++i)
66 {
68 std::vector<const dealii::DoFHandler<dim> *>(
69 {&dof_handlers[i][0], &dof_handlers[i][1]}),
70 std::vector<const dealii::AffineConstraints<number> *>(
71 {&constraints[i][0], &constraints[i][1]}),
73 }
74 }
75
79 void
81 {
82 initialize();
84 {
86 }
88 {
90 }
91 }
92
100 get_invm(TensorRank rank, unsigned int relative_level) const
101 {
102 Assert((rank == TensorRank::Scalar && calculate_scalar) ||
104 dealii::ExcInternalError("Requested invm that was not calculated"));
105 if (rank == TensorRank::Scalar)
106 {
107 return invm_scalar[relative_level];
108 }
109 // else
110 {
111 return invm_vector[relative_level];
112 }
113 }
114
122 get_jxw(TensorRank rank, unsigned int relative_level) const
123 {
124 Assert((rank == TensorRank::Scalar && calculate_scalar) ||
126 dealii::ExcInternalError("Requested invm that was not calculated"));
127 if (rank == TensorRank::Scalar)
128 {
129 return jxw_scalar[relative_level];
130 }
131 // else
132 {
133 return jxw_vector[relative_level];
134 }
135 }
136
144 get_invm_sqrt(TensorRank rank, unsigned int relative_level) const
145 {
146 Assert((rank == TensorRank::Scalar && calculate_scalar) ||
148 dealii::ExcInternalError("Requested invm that was not calculated"));
149 if (rank == TensorRank::Scalar)
150 {
151 return invm_sqrt_scalar[relative_level];
152 }
153 // else
154 {
155 return invm_sqrt_vector[relative_level];
156 }
157 }
158
159 std::vector<const SolutionVector<number> *>
160 get_invm(const std::vector<FieldAttributes> &field_container,
161 const std::set<unsigned int> &field_indices,
162 unsigned int relative_level) const
163 {
164 const unsigned int num_blocks = field_indices.size();
165 std::vector<const SolutionVector<number> *> out;
166 out.reserve(num_blocks);
167 for (unsigned int field_index : field_indices)
168 {
169 out.push_back(&get_invm(field_container[field_index].field_type, relative_level));
170 }
171 return out;
172 }
173
174 std::vector<const SolutionVector<number> *>
175 get_jxw(const std::vector<FieldAttributes> &field_container,
176 const std::set<unsigned int> &field_indices,
177 unsigned int relative_level) const
178 {
179 const unsigned int num_blocks = field_indices.size();
180 std::vector<const SolutionVector<number> *> out;
181 out.reserve(num_blocks);
182 for (unsigned int field_index : field_indices)
183 {
184 out.push_back(&get_jxw(field_container[field_index].field_type, relative_level));
185 }
186 return out;
187 }
188
189 std::vector<const SolutionVector<number> *>
190 get_invm_sqrt(const std::vector<FieldAttributes> &field_container,
191 const std::set<unsigned int> &field_indices,
192 unsigned int relative_level) const
193 {
194 const unsigned int num_blocks = field_indices.size();
195 std::vector<const SolutionVector<number> *> out;
196 out.reserve(num_blocks);
197 for (unsigned int field_index : field_indices)
198 {
199 out.push_back(
200 &get_invm_sqrt(field_container[field_index].field_type, relative_level));
201 }
202 return out;
203 }
204
205private:
209 void
211 {
212 for (unsigned int i = 0; i < num_levels; ++i)
213 {
215 {
216 jxw_scalar[i].reinit(data[i].get_vector_partitioner(0));
217 invm_scalar[i].reinit(data[i].get_vector_partitioner(0));
218 invm_sqrt_scalar[i].reinit(data[i].get_vector_partitioner(0));
219 }
221 {
222 jxw_vector[i].reinit(data[i].get_vector_partitioner(1));
223 invm_vector[i].reinit(data[i].get_vector_partitioner(1));
224 invm_sqrt_vector[i].reinit(data[i].get_vector_partitioner(1));
225 }
226 }
227 }
228
232 void
234 {
235 for (unsigned int i = 0; i < data.size(); ++i)
236 {
237 data[i].cell_loop(&InvMManager::compute_local_scalar, this, jxw_scalar[i], 0);
239 //
241 jxw_scalar[i].update_ghost_values();
242 invm_scalar[i].update_ghost_values();
243 invm_sqrt_scalar[i].update_ghost_values();
244 }
245 }
246
247 void
249 {
250 for (unsigned int i = 0; i < data.size(); ++i)
251 {
252 data[i].cell_loop(&InvMManager::compute_local_vector, this, jxw_vector[i], 0);
254 //
256 jxw_vector[i].update_ghost_values();
257 invm_vector[i].update_ghost_values();
258 invm_sqrt_vector[i].update_ghost_values();
259 }
260 }
261
262 void
263 compute_local_scalar(const MatrixFree<dim, number> &_data,
265 [[maybe_unused]] const int &src,
266 const std::pair<unsigned int, unsigned int> &cell_range) const
267 {
268 dealii::FEEvaluation<dim, degree, degree + 1, 1, number> fe_eval(_data, 0);
269 for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
270 {
271 fe_eval.reinit(cell);
272 for (unsigned int quad = 0; quad < SystemWide<dim, degree>::quadrature.size();
273 ++quad)
274 {
275 fe_eval.submit_value(dealii::make_vectorized_array<number>(1.0), quad);
276 }
277 fe_eval.integrate_scatter(dealii::EvaluationFlags::values, dst);
278 }
279 }
280
281 void
282 compute_local_vector(const MatrixFree<dim, number> &_data,
284 [[maybe_unused]] const int &src,
285 const std::pair<unsigned int, unsigned int> &cell_range) const
286 {
287 dealii::FEEvaluation<dim, degree, degree + 1, dim, number> fe_eval(_data, 1);
288 for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
289 {
290 fe_eval.reinit(cell);
291 for (unsigned int quad = 0; quad < SystemWide<dim, degree>::quadrature.size();
292 ++quad)
293 {
294 fe_eval.submit_value(one, quad);
295 }
296 fe_eval.integrate_scatter(dealii::EvaluationFlags::values, dst);
297 }
298 }
299
300 void
302 {
303 src.update_ghost_values();
304 dst.update_ghost_values();
305 Assert(dst.size() == src.size(), dealii::ExcInternalError());
306 for (unsigned int i = 0; i < src.locally_owned_size(); ++i)
307 {
308 number src_el = src.local_element(i);
309 // for some reason, some elements are zero
310 dst.local_element(i) = src_el == 0 ? 0.0 : 1.0 / src_el;
311 }
312 }
313
314 void
316 {
317 src.update_ghost_values();
318 dst.update_ghost_values();
319 Assert(dst.size() == src.size(), dealii::ExcInternalError());
320 for (unsigned int i = 0; i < src.locally_owned_size(); ++i)
321 {
322 dst.local_element(i) = std::sqrt(src.local_element(i));
323 }
324 }
325
329 std::vector<MatrixFree<dim, number>> data;
330
331 unsigned int num_levels;
332
333 bool calculate_scalar = false;
334 bool calculate_vector = false;
335
339 std::vector<SolutionVector<number>> jxw_scalar;
340 std::vector<SolutionVector<number>> jxw_vector;
341 std::vector<SolutionVector<number>> invm_scalar;
342 std::vector<SolutionVector<number>> invm_vector;
343 std::vector<SolutionVector<number>> invm_sqrt_scalar;
344 std::vector<SolutionVector<number>> invm_sqrt_vector;
345
346 inline static const VectorValue one = []()
347 {
348 VectorValue one1;
349 for (unsigned int i = 0; i < dim; ++i)
350 {
351 one1[i] = 1.0;
352 }
353 return one1;
354 }();
355};
356
357PRISMS_PF_END_NAMESPACE
The class handles the generation and application of boundary conditions based on the user-inputs.
Definition constraint_manager.h:50
const std::vector< std::array< dealii::AffineConstraints< number >, 2 > > & get_generic_constraints_levels() const
Getter function for the constraints.
Definition constraint_manager.cc:88
Class that manages the deal.II DoFHandlers.
Definition dof_manager.h:25
const std::vector< std::array< dealii::DoFHandler< dim >, 2 > > & get_dof_handlers_levels() const
Getter function for the scalar and vector DoFHandlers.
Definition dof_manager.cc:93
InvMManager(const DoFManager< dim, degree > &dof_manager, const ConstraintManager< dim, degree, number > &constraint_manager, bool _calculate_scalar, bool _calculate_vector)
Constructor.
Definition invm_manager.h:39
std::vector< const SolutionVector< number > * > get_invm(const std::vector< FieldAttributes > &field_container, const std::set< unsigned int > &field_indices, unsigned int relative_level) const
Definition invm_manager.h:160
void compute_local_vector(const MatrixFree< dim, number > &_data, SolutionVector< number > &dst, const int &src, const std::pair< unsigned int, unsigned int > &cell_range) const
Definition invm_manager.h:282
static const VectorValue one
Definition invm_manager.h:346
std::vector< SolutionVector< number > > jxw_scalar
Vector that stores element volumes.
Definition invm_manager.h:339
void compute_local_scalar(const MatrixFree< dim, number > &_data, SolutionVector< number > &dst, const int &src, const std::pair< unsigned int, unsigned int > &cell_range) const
Definition invm_manager.h:263
dealii::VectorizedArray< number > ScalarValue
Definition invm_manager.h:30
unsigned int num_levels
Definition invm_manager.h:331
std::vector< SolutionVector< number > > invm_sqrt_vector
Definition invm_manager.h:344
bool calculate_vector
Definition invm_manager.h:334
std::vector< SolutionVector< number > > invm_sqrt_scalar
Definition invm_manager.h:343
std::vector< SolutionVector< number > > invm_vector
Definition invm_manager.h:342
void compute_invm()
Recompute the invm vectors.
Definition invm_manager.h:80
bool calculate_scalar
Definition invm_manager.h:333
const SolutionVector< number > & get_invm(TensorRank rank, unsigned int relative_level) const
Get the invm vector for a given rank and level.
Definition invm_manager.h:100
std::vector< SolutionVector< number > > invm_scalar
Definition invm_manager.h:341
dealii::Tensor< 1, dim, ScalarValue > VectorValue
Definition invm_manager.h:31
std::vector< SolutionVector< number > > jxw_vector
Definition invm_manager.h:340
std::vector< const SolutionVector< number > * > get_jxw(const std::vector< FieldAttributes > &field_container, const std::set< unsigned int > &field_indices, unsigned int relative_level) const
Definition invm_manager.h:175
void sqrt(SolutionVector< number > &dst, const SolutionVector< number > &src) const
Definition invm_manager.h:315
void compute_vector_invm()
Definition invm_manager.h:248
void compute_scalar_invm()
Compute element volume for the triangulation.
Definition invm_manager.h:233
std::vector< MatrixFree< dim, number > > data
Matrix-free object.
Definition invm_manager.h:329
const SolutionVector< number > & get_jxw(TensorRank rank, unsigned int relative_level) const
Get the integrated jxw vector for a given rank and level.
Definition invm_manager.h:122
std::vector< const SolutionVector< number > * > get_invm_sqrt(const std::vector< FieldAttributes > &field_container, const std::set< unsigned int > &field_indices, unsigned int relative_level) const
Definition invm_manager.h:190
void invert(SolutionVector< number > &dst, const SolutionVector< number > &src) const
Definition invm_manager.h:301
const SolutionVector< number > & get_invm_sqrt(TensorRank rank, unsigned int relative_level) const
Get the integrated jxw vector for a given rank and level.
Definition invm_manager.h:144
void initialize()
Initialize.
Definition invm_manager.h:210
void reinit(const DoFManager< dim, degree > &dof_manager, const ConstraintManager< dim, degree, number > &constraint_manager)
Definition invm_manager.h:58
static const dealii::QGaussLobatto< dim > quadrature
Quadrature rule.
Definition system_wide.h:41
static const dealii::MappingQ1< dim > mapping
Mappings to and from reference cell.
Definition system_wide.h:36
typename BlockVector< number >::BlockType SolutionVector
Typedef for solution vector.
Definition group_solution_handler.h:35
Definition conditional_ostreams.cc:20
TensorRank
Tensor rank of the field.
Definition type_enums.h:52
@ Vector
Definition type_enums.h:55
@ Scalar
Definition type_enums.h:54