3#include <deal.II/base/tensor.h>
4#include <deal.II/base/vectorization.h>
6#include <deal.II/lac/la_parallel_vector.h>
8#include <deal.II/matrix_free/matrix_free.h>
9#include <deal.II/matrix_free/operators.h>
18 template <
int dim,
int n_components,
typename number>
20 const dealii::MatrixFree<dim, number> &matrix_free,
21 const unsigned int dof_no,
22 const unsigned int quad_no)
23 : fe_cell_evaluator(matrix_free, dof_no, quad_no)
28 template <
int dim,
int n_components,
typename number>
30 const dealii::FEEvaluation<dim, -1, 0, n_components, number, VectorizedArrayType>
32 : fe_cell_evaluator(fe_evaluation)
37 template <
int dim,
int n_components,
typename number>
41 cell_batch_index = cell_batch_index_in;
42 fe_cell_evaluator.reinit(cell_batch_index);
43 compute_intra_cell_face_sizes();
45 dof_values_initialized =
false;
46 subcell_values_initialized =
false;
47 subcell_values_submitted =
false;
48 subcell_fluxes_submitted =
false;
50 is_reinitialized =
true;
53 template <
int dim,
int n_components,
typename number>
56 const dealii::LinearAlgebra::distributed::Vector<number> &src_vector,
57 const std::bitset<n_lanes> &mask)
59 Assert(is_reinitialized,
61 "FESubcellEvaluation has not been reinitialized. Call reinit() before evaluate()."));
62 fe_cell_evaluator.read_dof_values(src_vector, 0, mask);
64 dof_values_initialized =
true;
67 template <
int dim,
int n_components,
typename number>
70 const dealii::EvaluationFlags::EvaluationFlags evaluation_flags)
72 Assert(dof_values_initialized,
74 "DoF values have not been initialized. Call read_dof_values() before evaluate()."));
76 project_dof_values_to_subcell_values(evaluation_flags);
79 template <
int dim,
int n_components,
typename number>
82 const dealii::LinearAlgebra::distributed::Vector<number> &input_vector,
83 const dealii::EvaluationFlags::EvaluationFlags evaluation_flags,
84 const std::bitset<n_lanes> &mask)
86 read_dof_values(input_vector, mask);
87 evaluate(evaluation_flags);
90 template <
int dim,
int n_components,
typename number>
95 AssertIndexRange(subcell_index, n_subcells_total);
96 Assert(subcell_values_initialized,
98 "Subcell values have not been initialized. Call evaluate() before get_value()."));
99 return subcell_values[subcell_index];
102 template <
int dim,
int n_components,
typename number>
105 const unsigned int subcell_face_index,
108 AssertIndexRange(subcell_face_index, n_intra_cell_faces);
109 Assert(subcell_values_initialized,
111 "Subcell values have not been initialized. Call evaluate() before get_value()."));
112 return subcell_values[face_adjacent_subcell_index(subcell_face_index, interior_face)];
115 template <
int dim,
int n_components,
typename number>
120 AssertIndexRange(subcell_index, n_subcells_total);
122 subcell_gradients_initialized,
124 "Subcell gradients have not been initialized. Call evaluate() before get_gradient()."));
125 return subcell_gradients[subcell_index];
128 template <
int dim,
int n_components,
typename number>
133 AssertIndexRange(subcell_index, n_subcells_total);
134 submitted_subcell_values[subcell_index] = value;
135 subcell_values_submitted =
true;
138 template <
int dim,
int n_components,
typename number>
143 AssertIndexRange(subcell_face_index, n_intra_cell_faces);
144 intra_cell_face_fluxes[subcell_face_index] = value;
145 subcell_fluxes_submitted =
true;
148 template <
int dim,
int n_components,
typename number>
153 subcell_values_submitted or subcell_fluxes_submitted,
155 "Subcell values or fluxes have not been submitted. Call submit_value() or submit_flux() before integrate()."));
157 if (subcell_values_submitted)
159 for (
unsigned int subcell : subcell_indices())
160 integrated_values_buffer[subcell] = submitted_subcell_values[subcell];
164 std::ranges::fill(integrated_values_buffer,
value_type());
167 if (subcell_fluxes_submitted)
169 for (
unsigned int subcell_face : subcell_face_indices())
171 const unsigned int interior_subcell_index =
172 face_adjacent_subcell_index(subcell_face,
true);
173 const unsigned int exterior_subcell_index =
174 face_adjacent_subcell_index(subcell_face,
false);
176 integrated_values_buffer[interior_subcell_index] +=
177 intra_cell_face_fluxes[subcell_face] * subcell_face_size(subcell_face) /
178 subcell_size(interior_subcell_index);
179 integrated_values_buffer[exterior_subcell_index] -=
180 intra_cell_face_fluxes[subcell_face] * subcell_face_size(subcell_face) /
181 subcell_size(exterior_subcell_index);
185 project_subcell_values_to_dof_values(integrated_values_buffer);
188 template <
int dim,
int n_components,
typename number>
191 dealii::LinearAlgebra::distributed::Vector<number> &dst_vector,
192 const std::bitset<n_lanes> &mask)
195 distribute_local_to_global(dst_vector, mask);
198 template <
int dim,
int n_components,
typename number>
201 dealii::LinearAlgebra::distributed::Vector<number> &dst_vector,
202 const std::bitset<n_lanes> &mask)
204 fe_cell_evaluator.distribute_local_to_global(dst_vector, 0, mask);
207 template <
int dim,
int n_components,
typename number>
210 dealii::LinearAlgebra::distributed::Vector<number> &dst_vector,
211 const std::bitset<n_lanes> &mask)
213 fe_cell_evaluator.set_dof_values(dst_vector, 0, mask);
216 template <
int dim,
int n_components,
typename number>
217 std::ranges::iota_view<unsigned int, unsigned int>
220 return {0U, n_subcells_total};
223 template <
int dim,
int n_components,
typename number>
224 std::ranges::iota_view<unsigned int, unsigned int>
227 return {0U, n_intra_cell_faces};
230 template <
int dim,
int n_components,
typename number>
238 "FESubcellEvaluation has not been reinitialized. Call reinit() before subcell_size()."));
239 AssertIndexRange(subcell_index, n_subcells_total);
240 return fe_cell_evaluator.JxW(subcell_index);
243 template <
int dim,
int n_components,
typename number>
251 "FESubcellEvaluation has not been reinitialized. Call reinit() before subcell_face_size()."));
252 AssertIndexRange(subcell_face_index, n_intra_cell_faces);
254 return intra_cell_face_sizes[subcell_face_index];
257 template <
int dim,
int n_components,
typename number>
260 const unsigned int subcell_index)
const -> dealii::Point<dim, VectorizedArrayType>
262 AssertIndexRange(subcell_index, n_subcells_total);
266 "FESubcellEvaluation has not been reinitialized. Call reinit() before subcell_location()."));
267 return fe_cell_evaluator.quadrature_point(subcell_index);
270 template <
int dim,
int n_components,
typename number>
274 return n_subcells_total;
277 template <
int dim,
int n_components,
typename number>
278 dealii::Tensor<1, dim, dealii::VectorizedArray<number>>
280 const unsigned int subcell_face_index)
const
282 AssertIndexRange(subcell_face_index, n_intra_cell_faces);
286 "FESubcellEvaluation has not been reinitialized. Call reinit() before subcell_face_normal_vector()."));
287 const unsigned int face_normal_direction =
288 compute_reference_coordinates_normal_direction(subcell_face_index);
289 dealii::Tensor<1, dim, VectorizedArrayType> normal_vector;
291 return normal_vector;
294 template <
int dim,
int n_components,
typename number>
295 std::pair<unsigned int, unsigned int>
297 const unsigned int subcell_face_index)
const
299 AssertIndexRange(subcell_face_index, n_intra_cell_faces);
303 "FESubcellEvaluation has not been reinitialized. Call reinit() before subcell_face_interior_exterior_indices()."));
304 const unsigned int interior_subcell_index =
305 face_adjacent_subcell_index(subcell_face_index,
true);
306 const unsigned int exterior_subcell_index =
307 face_adjacent_subcell_index(subcell_face_index,
false);
308 return {interior_subcell_index, exterior_subcell_index};
311 template <
int dim,
int n_components,
typename number>
315 n_subcells_total = fe_cell_evaluator.n_q_points;
316 this->n_subcells_1d = fe_cell_evaluator.get_shape_info().data[0].n_q_points_1d;
319 dim * (n_subcells_1d - 1) * dealii::Utilities::fixed_power<dim - 1>(n_subcells_1d);
321 subcell_values.resize(n_subcells_total);
322 subcell_gradients.resize(n_subcells_total);
323 submitted_subcell_values.resize(n_subcells_total);
324 intra_cell_face_fluxes.resize(n_intra_cell_faces);
325 intra_cell_face_sizes.resize(n_intra_cell_faces);
326 subcell_values_to_project_buffer.resize(n_components * n_subcells_total);
327 integrated_values_buffer.resize(n_subcells_total);
330 template <
int dim,
int n_components,
typename number>
334 Assert(fe_cell_evaluator.get_cell_type() == dealii::internal::MatrixFreeFunctions::cartesian,
335 dealii::ExcNotImplemented());
342 const dealii::Quadrature<1> &quadrature_1d =
343 fe_cell_evaluator.get_shape_info().data[0].quadrature;
345 for (
const unsigned int subcell_face : subcell_face_indices())
347 const unsigned int face_normal_direction =
348 compute_reference_coordinates_normal_direction(subcell_face);
349 const unsigned int interior_subcell = face_adjacent_subcell_index(subcell_face,
true);
350 const unsigned int interior_subcell_index_1d =
351 (interior_subcell / dealii::Utilities::pow(n_subcells_1d, face_normal_direction)) %
354 intra_cell_face_sizes[subcell_face] =
355 fe_cell_evaluator.JxW(interior_subcell) *
356 fe_cell_evaluator.inverse_jacobian(
357 interior_subcell)[face_normal_direction][face_normal_direction] /
358 quadrature_1d.weight(interior_subcell_index_1d);
362 template <
int dim,
int n_components,
typename number>
365 const dealii::EvaluationFlags::EvaluationFlags evaluation_flags)
367 AssertDimension(subcell_values.size(), fe_cell_evaluator.n_q_points);
369 fe_cell_evaluator.evaluate(evaluation_flags);
371 for (
unsigned int q : fe_cell_evaluator.quadrature_point_indices())
373 if (evaluation_flags & dealii::EvaluationFlags::values)
374 subcell_values[q] = fe_cell_evaluator.get_value(q);
375 if (evaluation_flags & dealii::EvaluationFlags::gradients)
376 subcell_gradients[q] = fe_cell_evaluator.get_gradient(q);
379 if (evaluation_flags & dealii::EvaluationFlags::values)
380 subcell_values_initialized =
true;
381 if (evaluation_flags & dealii::EvaluationFlags::gradients)
382 subcell_gradients_initialized =
true;
385 template <
int dim,
int n_components,
typename number>
388 const std::vector<value_type> &values_to_project)
390 AssertDimension(values_to_project.size(), fe_cell_evaluator.n_q_points);
392 dealii::MatrixFreeOperators::CellwiseInverseMassMatrix<dim, -1, n_components, number> inverse(
395 for (
unsigned int subcell : subcell_indices())
397 if constexpr (n_components == 1)
398 subcell_values_to_project_buffer[subcell] = values_to_project[subcell];
400 for (
unsigned int c = 0; c < n_components; ++c)
401 subcell_values_to_project_buffer[c * n_subcells_total + subcell] =
402 values_to_project[subcell][c];
404 inverse.transform_from_q_points_to_basis(n_components,
405 subcell_values_to_project_buffer.data(),
406 fe_cell_evaluator.begin_dof_values());
409 template <
int dim,
int n_components,
typename number>
412 const unsigned int subcell_face_index)
const
414 const unsigned int n_faces_per_direction =
415 (n_subcells_1d - 1) * dealii::Utilities::fixed_power<dim - 1>(n_subcells_1d);
417 return subcell_face_index / n_faces_per_direction;
420 template <
int dim,
int n_components,
typename number>
423 const unsigned int subcell_face_index,
424 const bool interior_face)
const
426 AssertIndexRange(subcell_face_index, n_intra_cell_faces);
428 const unsigned int n_faces_per_direction =
429 (n_subcells_1d - 1) * dealii::Utilities::fixed_power<dim - 1>(n_subcells_1d);
431 const unsigned int face_normal_direction =
432 compute_reference_coordinates_normal_direction(subcell_face_index);
434 unsigned int frame_local_index =
435 subcell_face_index - face_normal_direction * n_faces_per_direction;
436 if (face_normal_direction == dim - 1)
439 return frame_local_index;
441 return frame_local_index + dealii::Utilities::pow(n_subcells_1d, face_normal_direction);
443 else if (dim == 3 and face_normal_direction == 1)
445 const unsigned int layer = frame_local_index / (n_subcells_1d * (n_subcells_1d - 1));
447 return frame_local_index + layer * n_subcells_1d;
449 return frame_local_index + (layer + 1) * n_subcells_1d;
453 const unsigned int layer = frame_local_index / (n_subcells_1d - 1);
455 return frame_local_index + layer;
457 return frame_local_index + layer + 1;
dealii::FEEvaluation< dim, -1, 0, n_components, number, VectorizedArrayType >::value_type value_type
Definition fe_subcell_evaluation.hpp:192
void submit_value(const unsigned int subcell_index, const value_type &value)
Definition fe_subcell_evaluation.templates.hpp:130
unsigned int compute_reference_coordinates_normal_direction(const unsigned int subcell_face_index) const
Definition fe_subcell_evaluation.templates.hpp:411
value_type get_value(const unsigned int subcell_index) const
Definition fe_subcell_evaluation.templates.hpp:92
void integrate()
Definition fe_subcell_evaluation.templates.hpp:150
value_type get_face_value(const unsigned int subcell_face_index, const bool interior_value) const
Definition fe_subcell_evaluation.templates.hpp:104
std::ranges::iota_view< unsigned int, unsigned int > subcell_indices() const
Definition fe_subcell_evaluation.templates.hpp:218
void gather_evaluate(const dealii::LinearAlgebra::distributed::Vector< number > &input_vector, const dealii::EvaluationFlags::EvaluationFlags evaluation_flags, const std::bitset< n_lanes > &mask=std::bitset< n_lanes >().flip())
Definition fe_subcell_evaluation.templates.hpp:81
std::ranges::iota_view< unsigned int, unsigned int > subcell_face_indices() const
Definition fe_subcell_evaluation.templates.hpp:225
dealii::Tensor< 1, dim, VectorizedArrayType > subcell_face_normal_vector(const unsigned int subcell_face_index) const
Definition fe_subcell_evaluation.templates.hpp:279
void evaluate(const dealii::EvaluationFlags::EvaluationFlags evaluation_flags)
Definition fe_subcell_evaluation.templates.hpp:69
void distribute_local_to_global(dealii::LinearAlgebra::distributed::Vector< number > &dst_vector, const std::bitset< n_lanes > &mask=std::bitset< n_lanes >().flip())
Definition fe_subcell_evaluation.templates.hpp:200
void read_dof_values(const dealii::LinearAlgebra::distributed::Vector< number > &src_vector, const std::bitset< n_lanes > &mask=std::bitset< n_lanes >().flip())
Definition fe_subcell_evaluation.templates.hpp:55
gradient_type get_gradient(const unsigned int subcell_index) const
Definition fe_subcell_evaluation.templates.hpp:117
dealii::FEEvaluation< dim, -1, 0, n_components, number, VectorizedArrayType >::gradient_type gradient_type
Definition fe_subcell_evaluation.hpp:195
void reinit(const unsigned int cell_batch_index)
Definition fe_subcell_evaluation.templates.hpp:39
std::pair< unsigned int, unsigned int > subcell_face_interior_exterior_indices(const unsigned int subcell_face_index) const
Definition fe_subcell_evaluation.templates.hpp:296
unsigned int face_adjacent_subcell_index(const unsigned int subcell_face_index, const bool interior_face) const
Definition fe_subcell_evaluation.templates.hpp:422
dealii::Point< dim, VectorizedArrayType > subcell_location(const unsigned int subcell_index) const
Definition fe_subcell_evaluation.templates.hpp:259
VectorizedArrayType subcell_size(const unsigned int subcell_index) const
Definition fe_subcell_evaluation.templates.hpp:232
FESubcellEvaluation(const dealii::MatrixFree< dim, number > &matrix_free, const unsigned int dof_no, const unsigned int quad_no)
Definition fe_subcell_evaluation.templates.hpp:19
void project_dof_values_to_subcell_values(const dealii::EvaluationFlags::EvaluationFlags evaluation_flags)
Definition fe_subcell_evaluation.templates.hpp:364
dealii::VectorizedArray< number > VectorizedArrayType
Definition fe_subcell_evaluation.hpp:189
VectorizedArrayType subcell_face_size(const unsigned int subcell_face_index) const
Definition fe_subcell_evaluation.templates.hpp:245
void project_subcell_values_to_dof_values(const std::vector< value_type > &values_to_project)
Definition fe_subcell_evaluation.templates.hpp:387
void submit_flux(const unsigned int subcell_face_index, const value_type &flux)
Definition fe_subcell_evaluation.templates.hpp:140
void compute_intra_cell_face_sizes()
Definition fe_subcell_evaluation.templates.hpp:332
void set_dof_values(dealii::LinearAlgebra::distributed::Vector< number > &dst, const std::bitset< n_lanes > &mask=std::bitset< n_lanes >().flip())
Definition fe_subcell_evaluation.templates.hpp:209
void setup_internal_data_structures()
Definition fe_subcell_evaluation.templates.hpp:313
void integrate_scatter(dealii::LinearAlgebra::distributed::Vector< number > &dst_vector, const std::bitset< n_lanes > &mask=std::bitset< n_lanes >().flip())
Definition fe_subcell_evaluation.templates.hpp:190
unsigned n_subcells() const
Definition fe_subcell_evaluation.templates.hpp:272
Interface for a general preconditioner.
Definition boundary_condition_functions.hpp:17