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/exceptions.h>
7#include <deal.II/base/vectorization.h>
8#include <deal.II/matrix_free/fe_evaluation.h>
9
12
13#include <prismspf/config.h>
14
16
20template <unsigned int dim, unsigned int degree, typename number>
22{
23public:
24 using ScalarValue = dealii::VectorizedArray<number>;
25 using VectorValue = dealii::Tensor<1, dim, ScalarValue>;
26
30 InvMManager() = default;
31
35 void
36 reinit(const MatrixFreeManager<dim, number> &matrix_free_manager);
37
41 void
43
50 get_invm(TensorRank rank, unsigned int relative_level = -1) const;
51
58 get_jxw(TensorRank rank, unsigned int relative_level = -1) const;
59
66 get_invm_sqrt(TensorRank rank, unsigned int relative_level = -1) const;
67
68 std::vector<const SolutionVector<number> *>
69 get_invm(const std::vector<FieldAttributes> &field_container,
70 const std::set<unsigned int> &field_indices,
71 unsigned int relative_level = -1) const;
72
73 std::vector<const SolutionVector<number> *>
74 get_jxw(const std::vector<FieldAttributes> &field_container,
75 const std::set<unsigned int> &field_indices,
76 unsigned int relative_level = -1) const;
77
78 std::vector<const SolutionVector<number> *>
79 get_invm_sqrt(const std::vector<FieldAttributes> &field_container,
80 const std::set<unsigned int> &field_indices,
81 unsigned int relative_level = -1) const;
82
83private: // todo: move to outside class body
86 {
87 Assert(mf_manager_ptr != nullptr, dealii::ExcNotInitialized());
88 return *mf_manager_ptr;
89 }
90
94 void
96 {
97 const MatrixFree<dim, number> &matrix_free = mf_manager().get_generic_matrix_free();
98 jxw_scalar.reinit(matrix_free.get_vector_partitioner(0));
99 invm_scalar.reinit(matrix_free.get_vector_partitioner(0));
100 invm_sqrt_scalar.reinit(matrix_free.get_vector_partitioner(0));
101
102 jxw_vector.reinit(matrix_free.get_vector_partitioner(1));
103 invm_vector.reinit(matrix_free.get_vector_partitioner(1));
104 invm_sqrt_vector.reinit(matrix_free.get_vector_partitioner(1));
105 for (unsigned int i = 0; i < num_levels; ++i)
106 {
107 const MatrixFree<dim, number> &mg_matrix_free =
108 mf_manager().get_mg_generic_matrix_free(i);
109 mg_jxw_scalar[i].reinit(mg_matrix_free.get_vector_partitioner(0));
110 mg_invm_scalar[i].reinit(mg_matrix_free.get_vector_partitioner(0));
111 mg_invm_sqrt_scalar[i].reinit(mg_matrix_free.get_vector_partitioner(0));
112
113 mg_jxw_vector[i].reinit(mg_matrix_free.get_vector_partitioner(1));
114 mg_invm_vector[i].reinit(mg_matrix_free.get_vector_partitioner(1));
115 mg_invm_sqrt_vector[i].reinit(mg_matrix_free.get_vector_partitioner(1));
116 }
117 }
118
122 void
124 {
125 const MatrixFree<dim, number> &matrix_free = mf_manager().get_generic_matrix_free();
126 matrix_free.cell_loop(&InvMManager::compute_local_scalar, this, jxw_scalar, 0);
128 //
130 jxw_scalar.update_ghost_values();
131 invm_scalar.update_ghost_values();
132 invm_sqrt_scalar.update_ghost_values();
133 for (unsigned int i = 0; i < num_levels; ++i)
134 {
135 const MatrixFree<dim, number> &mg_matrix_free =
136 mf_manager().get_mg_generic_matrix_free(i);
137 mg_matrix_free.cell_loop(&InvMManager::compute_local_scalar,
138 this,
139 mg_jxw_scalar[i],
140 0);
142 //
144 mg_jxw_scalar[i].update_ghost_values();
145 mg_invm_scalar[i].update_ghost_values();
146 mg_invm_sqrt_scalar[i].update_ghost_values();
147 }
148 }
149
150 void
152 {
153 const MatrixFree<dim, number> &matrix_free = mf_manager().get_generic_matrix_free();
154 matrix_free.cell_loop(&InvMManager::compute_local_vector, this, jxw_vector, 0);
156 //
158 jxw_vector.update_ghost_values();
159 invm_vector.update_ghost_values();
160 invm_sqrt_vector.update_ghost_values();
161 for (unsigned int i = 0; i < num_levels; ++i)
162 {
163 const MatrixFree<dim, number> &mg_matrix_free =
164 mf_manager().get_mg_generic_matrix_free(i);
165 mg_matrix_free.cell_loop(&InvMManager::compute_local_vector,
166 this,
167 mg_jxw_vector[i],
168 0);
170 //
172 mg_jxw_vector[i].update_ghost_values();
173 mg_invm_vector[i].update_ghost_values();
174 mg_invm_sqrt_vector[i].update_ghost_values();
175 }
176 }
177
178 void
179 compute_local_scalar(const MatrixFree<dim, number> &_data,
181 [[maybe_unused]] const int &src,
182 const std::pair<unsigned int, unsigned int> &cell_range) const
183 {
184 dealii::FEEvaluation<dim, degree, degree + 1, 1, number> fe_eval(_data, 0);
185 for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
186 {
187 fe_eval.reinit(cell);
188 for (unsigned int quad = 0; quad < SystemWide<dim, degree>::quadrature.size();
189 ++quad)
190 {
191 fe_eval.submit_value(dealii::make_vectorized_array<number>(1.0), quad);
192 }
193 fe_eval.integrate_scatter(dealii::EvaluationFlags::values, dst);
194 }
195 }
196
197 void
198 compute_local_vector(const MatrixFree<dim, number> &_data,
200 [[maybe_unused]] const int &src,
201 const std::pair<unsigned int, unsigned int> &cell_range) const
202 {
203 dealii::FEEvaluation<dim, degree, degree + 1, dim, number> fe_eval(_data, 1);
204 for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell)
205 {
206 fe_eval.reinit(cell);
207 for (unsigned int quad = 0; quad < SystemWide<dim, degree>::quadrature.size();
208 ++quad)
209 {
210 fe_eval.submit_value(one, quad);
211 }
212 fe_eval.integrate_scatter(dealii::EvaluationFlags::values, dst);
213 }
214 }
215
216 void
218 {
219 src.update_ghost_values();
220 dst.update_ghost_values();
221 Assert(dst.size() == src.size(), dealii::ExcInternalError());
222 for (unsigned int i = 0; i < src.locally_owned_size(); ++i)
223 {
224 number src_el = src.local_element(i);
225 // for some reason, some elements are zero
226 dst.local_element(i) = src_el == 0 ? 0.0 : 1.0 / src_el;
227 }
228 }
229
230 void
232 {
233 src.update_ghost_values();
234 dst.update_ghost_values();
235 Assert(dst.size() == src.size(), dealii::ExcInternalError());
236 for (unsigned int i = 0; i < src.locally_owned_size(); ++i)
237 {
238 dst.local_element(i) = std::sqrt(src.local_element(i));
239 }
240 }
241
242 unsigned int num_levels = 0;
243
253 std::vector<SolutionVector<number>> mg_jxw_scalar;
254 std::vector<SolutionVector<number>> mg_jxw_vector;
255 std::vector<SolutionVector<number>> mg_invm_scalar;
256 std::vector<SolutionVector<number>> mg_invm_vector;
257 std::vector<SolutionVector<number>> mg_invm_sqrt_scalar;
258 std::vector<SolutionVector<number>> mg_invm_sqrt_vector;
259
261
262 inline static const VectorValue one = []()
263 {
264 VectorValue one1;
265 for (unsigned int i = 0; i < dim; ++i)
266 {
267 one1[i] = 1.0;
268 }
269 return one1;
270 }();
271};
272
273template <unsigned int dim, unsigned int degree, typename number>
274inline void
276 const MatrixFreeManager<dim, number> &matrix_free_manager)
277{
278 mf_manager_ptr = &matrix_free_manager;
279 num_levels = matrix_free_manager.get_generic_matrix_free_levels().size();
286 initialize();
287}
288
289template <unsigned int dim, unsigned int degree, typename number>
290inline void
296
297template <unsigned int dim, unsigned int degree, typename number>
298inline const SolutionVector<number> &
300 unsigned int relative_level) const
301{
302 if (relative_level == -1)
303 {
304 if (rank == TensorRank::Scalar)
305 {
306 return invm_scalar;
307 }
308 // else
309 {
310 return invm_vector;
311 }
312 }
313 if (rank == TensorRank::Scalar)
314 {
315 return mg_invm_scalar[relative_level];
316 }
317 // else
318 {
319 return mg_invm_vector[relative_level];
320 }
321}
322
323template <unsigned int dim, unsigned int degree, typename number>
324inline const SolutionVector<number> &
326 unsigned int relative_level) const
327{
328 if (relative_level == -1)
329 {
330 if (rank == TensorRank::Scalar)
331 {
332 return jxw_scalar;
333 }
334 // else
335 {
336 return jxw_vector;
337 }
338 }
339 if (rank == TensorRank::Scalar)
340 {
341 return mg_jxw_scalar[relative_level];
342 }
343 // else
344 {
345 return mg_jxw_vector[relative_level];
346 }
347}
348
349template <unsigned int dim, unsigned int degree, typename number>
350inline const SolutionVector<number> &
352 unsigned int relative_level) const
353{
354 if (relative_level == -1)
355 {
356 if (rank == TensorRank::Scalar)
357 {
358 return invm_sqrt_scalar;
359 }
360 // else
361 {
362 return invm_sqrt_vector;
363 }
364 }
365 if (rank == TensorRank::Scalar)
366 {
367 return mg_invm_sqrt_scalar[relative_level];
368 }
369 // else
370 {
371 return mg_invm_sqrt_vector[relative_level];
372 }
373}
374
375template <unsigned int dim, unsigned int degree, typename number>
376inline std::vector<const SolutionVector<number> *>
378 const std::vector<FieldAttributes> &field_container,
379 const std::set<unsigned int> &field_indices,
380 unsigned int relative_level) const
381{
382 const unsigned int num_blocks = field_indices.size();
383 std::vector<const SolutionVector<number> *> out;
384 out.reserve(num_blocks);
385 for (unsigned int field_index : field_indices)
386 {
387 out.push_back(&get_invm(field_container[field_index].field_type, relative_level));
388 }
389 return out;
390}
391
392template <unsigned int dim, unsigned int degree, typename number>
393inline std::vector<const SolutionVector<number> *>
395 const std::vector<FieldAttributes> &field_container,
396 const std::set<unsigned int> &field_indices,
397 unsigned int relative_level) const
398{
399 const unsigned int num_blocks = field_indices.size();
400 std::vector<const SolutionVector<number> *> out;
401 out.reserve(num_blocks);
402 for (unsigned int field_index : field_indices)
403 {
404 out.push_back(&get_jxw(field_container[field_index].field_type, relative_level));
405 }
406 return out;
407}
408
409template <unsigned int dim, unsigned int degree, typename number>
410inline std::vector<const SolutionVector<number> *>
412 const std::vector<FieldAttributes> &field_container,
413 const std::set<unsigned int> &field_indices,
414 unsigned int relative_level) const
415{
416 const unsigned int num_blocks = field_indices.size();
417 std::vector<const SolutionVector<number> *> out;
418 out.reserve(num_blocks);
419 for (unsigned int field_index : field_indices)
420 {
421 out.push_back(
422 &get_invm_sqrt(field_container[field_index].field_type, relative_level));
423 }
424 return out;
425}
426
427PRISMS_PF_END_NAMESPACE
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:198
const SolutionVector< number > & get_jxw(TensorRank rank, unsigned int relative_level=-1) const
Get the integrated jxw vector for a given rank and level.
Definition invm_manager.h:325
std::vector< SolutionVector< number > > mg_invm_vector
Definition invm_manager.h:256
static const VectorValue one
Definition invm_manager.h:262
std::vector< SolutionVector< number > > mg_invm_scalar
Definition invm_manager.h:255
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:179
std::vector< SolutionVector< number > > mg_jxw_vector
Definition invm_manager.h:254
dealii::VectorizedArray< number > ScalarValue
Definition invm_manager.h:24
unsigned int num_levels
Definition invm_manager.h:242
SolutionVector< number > invm_vector
Definition invm_manager.h:250
std::vector< SolutionVector< number > > mg_invm_sqrt_vector
Definition invm_manager.h:258
std::vector< SolutionVector< number > > mg_jxw_scalar
Definition invm_manager.h:253
SolutionVector< number > jxw_vector
Definition invm_manager.h:248
const MatrixFreeManager< dim, number > & mf_manager()
Definition invm_manager.h:85
void reinit(const MatrixFreeManager< dim, number > &matrix_free_manager)
Reserve space.
Definition invm_manager.h:275
SolutionVector< number > invm_sqrt_vector
Definition invm_manager.h:252
InvMManager()=default
Constructor.
SolutionVector< number > invm_sqrt_scalar
Definition invm_manager.h:251
void compute_invm()
Recompute the invm vectors.
Definition invm_manager.h:291
const SolutionVector< number > & get_invm_sqrt(TensorRank rank, unsigned int relative_level=-1) const
Get the integrated jxw vector for a given rank.
Definition invm_manager.h:351
dealii::Tensor< 1, dim, ScalarValue > VectorValue
Definition invm_manager.h:25
const MatrixFreeManager< dim, number > * mf_manager_ptr
Definition invm_manager.h:260
void sqrt(SolutionVector< number > &dst, const SolutionVector< number > &src) const
Definition invm_manager.h:231
std::vector< SolutionVector< number > > mg_invm_sqrt_scalar
Definition invm_manager.h:257
void compute_vector_invm()
Definition invm_manager.h:151
void compute_scalar_invm()
Compute element volume for the triangulation.
Definition invm_manager.h:123
SolutionVector< number > jxw_scalar
Vector that stores element volumes.
Definition invm_manager.h:247
void invert(SolutionVector< number > &dst, const SolutionVector< number > &src) const
Definition invm_manager.h:217
void initialize()
Initialize.
Definition invm_manager.h:95
const SolutionVector< number > & get_invm(TensorRank rank, unsigned int relative_level=-1) const
Get the invm vector for a given rank and level.
Definition invm_manager.h:299
SolutionVector< number > invm_scalar
Definition invm_manager.h:249
Containers for matrix free objects.
Definition matrix_free_manager.h:45
const std::vector< MatrixFree< dim, number > > & get_generic_matrix_free_levels() const
Definition matrix_free_manager.h:232
typename BlockVector< number >::BlockType SolutionVector
Typedef for solution vector.
Definition matrix_free_manager.h:38
Definition conditional_ostreams.cc:20
TensorRank
Tensor rank of the field.
Definition type_enums.h:52
@ Scalar
Definition type_enums.h:54