36template <
int dim,
int spacedim>
38 const unsigned int polynomial_degree)
39 :
MappingQ<dim, spacedim>(polynomial_degree)
40 , uses_level_info(false)
45template <
int dim,
int spacedim>
49 , support_point_cache(mapping.support_point_cache)
50 , uses_level_info(mapping.uses_level_info)
55template <
int dim,
int spacedim>
62 support_point_cache.reset();
63 clear_signal.disconnect();
68template <
int dim,
int spacedim>
69std::unique_ptr<Mapping<dim, spacedim>>
72 return std::make_unique<MappingQCache<dim, spacedim>>(*this);
77template <
int dim,
int spacedim>
86template <
int dim,
int spacedim>
100 const auto mapping_q =
102 if (mapping_q !=
nullptr && this->get_degree() == mapping_q->get_degree())
111 auto &fe_values = fe_values_all.
get();
112 if (fe_values.get() ==
nullptr)
117 std::vector<Point<dim>> quadrature_points;
120 this->polynomial_degree))
121 quadrature_points.push_back(quadrature_gl.point(i));
124 fe_values = std::make_unique<FEValues<dim, spacedim>>(
128 fe_values->reinit(cell);
129 return fe_values->get_quadrature_points();
136template <
int dim,
int spacedim>
142 &compute_points_on_cell)
144 clear_signal.disconnect();
146 [&]() ->
void { this->support_point_cache.reset(); });
148 support_point_cache =
149 std::make_shared<std::vector<std::vector<std::vector<Point<spacedim>>>>>(
160 (*support_point_cache)[cell->level()][cell->index()] =
161 compute_points_on_cell(cell);
163 (*support_point_cache)[cell->level()][cell->index()].size(),
164 Utilities::pow(this->get_degree() + 1, dim));
166 std::function<
void(
void *)>(),
172 uses_level_info =
true;
177template <
int dim,
int spacedim>
185 const bool function_describes_relative_displacement)
195 std::vector<Point<spacedim>> points;
197 const auto mapping_q =
200 if (mapping_q !=
nullptr && this->get_degree() == mapping_q->get_degree())
202 points = mapping_q->compute_mapping_support_points(cell);
209 auto &fe_values = fe_values_all.
get();
210 if (fe_values.get() ==
nullptr)
215 std::vector<Point<dim>> quadrature_points;
218 this->polynomial_degree))
219 quadrature_points.push_back(quadrature_gl.point(i));
222 fe_values = std::make_unique<FEValues<dim, spacedim>>(
226 fe_values->reinit(cell);
227 points = fe_values->get_quadrature_points();
230 for (
auto &p : points)
231 if (function_describes_relative_displacement)
232 p += transformation_function(cell, p);
234 p = transformation_function(cell, p);
239 uses_level_info =
true;
244template <
int dim,
int spacedim>
250 const bool function_describes_relative_displacement)
257 [&](
const auto &,
const auto &point) {
259 for (
unsigned int c = 0; c < spacedim; ++c)
260 new_point[c] = transformation_function.
value(point, c);
263 function_describes_relative_displacement);
265 uses_level_info =
true;
272 template <
typename VectorType>
274 copy_locally_owned_data_from(
275 const VectorType &vector,
280 temp.
reinit(vector.locally_owned_elements());
288template <
int dim,
int spacedim>
289template <
typename VectorType>
294 const VectorType &vector,
295 const bool vector_describes_relative_displacement)
302 const unsigned int is_fe_q =
304 const unsigned int is_fe_dgq =
307 const auto lexicographic_to_hierarchic_numbering =
310 this->get_degree()));
316 const IndexSet locally_relevant_dofs =
319 locally_relevant_dofs,
321 copy_locally_owned_data_from(vector, vector_ghosted);
332 const bool interpolation_of_values_is_needed =
333 ((is_fe_q || is_fe_dgq) && fe.
degree == this->get_degree()) ==
false;
340 const bool is_active_non_artificial_cell =
341 (cell_tria->is_active() == true) &&
342 (cell_tria->is_artificial() == false);
344 const typename DoFHandler<dim, spacedim>::cell_iterator cell_dofs(
345 &cell_tria->get_triangulation(),
350 const auto mapping_q =
351 dynamic_cast<const MappingQ<dim, spacedim> *>(&mapping);
355 ((vector_describes_relative_displacement ||
356 (is_active_non_artificial_cell == false)) &&
357 ((mapping_q != nullptr &&
358 this->get_degree() == mapping_q->get_degree()) ==
361 (is_active_non_artificial_cell && interpolation_of_values_is_needed) )
366 auto &fe_values = fe_values_all.get();
367 if (fe_values.get() == nullptr)
369 const QGaussLobatto<dim> quadrature_gl(this->polynomial_degree +
372 std::vector<Point<dim>> quadrature_points;
374 FETools::hierarchic_to_lexicographic_numbering<dim>(
375 this->polynomial_degree))
376 quadrature_points.push_back(quadrature_gl.point(i));
377 const Quadrature<dim> quadrature(quadrature_points);
379 fe_values = std::make_unique<FEValues<dim, spacedim>>(
381 interpolation_of_values_is_needed ?
383 static_cast<const FiniteElement<dim, spacedim> &>(fe_nothing),
385 update_quadrature_points | update_values);
388 if (interpolation_of_values_is_needed)
389 fe_values->reinit(cell_dofs);
391 fe_values->reinit(cell_tria);
399 if (vector_describes_relative_displacement ||
400 is_active_non_artificial_cell ==
false)
402 if (mapping_q !=
nullptr &&
403 this->get_degree() == mapping_q->get_degree())
404 result = mapping_q->compute_mapping_support_points(cell_tria);
406 result = fe_values_all.
get()->get_quadrature_points();
411 if (is_active_non_artificial_cell ==
false)
421 if (interpolation_of_values_is_needed ==
false)
425 std::vector<types::global_dof_index> dof_indices(
427 cell_dofs->get_dof_indices(dof_indices);
429 for (
unsigned int i = 0; i < dof_indices.size(); ++i)
436 if (vector_describes_relative_displacement)
437 result[
id.second][
id.first] +=
438 vector_ghosted(dof_indices[i]);
440 result[
id.second][
id.first] =
441 vector_ghosted(dof_indices[i]);
446 if (vector_describes_relative_displacement)
447 result[lexicographic_to_hierarchic_numbering[
id.second]]
448 [
id.first] += vector_ghosted(dof_indices[i]);
450 result[lexicographic_to_hierarchic_numbering[
id.second]]
451 [
id.first] = vector_ghosted(dof_indices[i]);
461 auto &fe_values = fe_values_all.
get();
463 std::vector<Vector<typename VectorType::value_type>> values(
464 fe_values->n_quadrature_points,
467 fe_values->get_function_values(vector_ghosted, values);
469 for (
unsigned int q = 0; q < fe_values->n_quadrature_points; ++q)
470 for (
unsigned int c = 0; c < spacedim; ++c)
471 if (vector_describes_relative_displacement)
472 result[q][c] += values[q][c];
474 result[q][c] = values[q][c];
480 uses_level_info =
false;
485template <
int dim,
int spacedim>
486template <
typename VectorType>
492 const bool vector_describes_relative_displacement)
502 const unsigned int is_fe_q =
504 const unsigned int is_fe_dgq =
507 const auto lexicographic_to_hierarchic_numbering =
510 this->get_degree()));
520 const IndexSet locally_relevant_dofs =
523 locally_relevant_dofs,
525 copy_locally_owned_data_from(vectors[l], vectors_ghosted[l]);
526 vectors_ghosted[l].update_ghost_values();
537 const bool interpolation_of_values_is_needed =
538 ((is_fe_q || is_fe_dgq) && fe.
degree == this->get_degree()) ==
false;
545 const bool is_non_artificial_cell =
546 cell_tria->level_subdomain_id() != numbers::artificial_subdomain_id;
548 const typename DoFHandler<dim, spacedim>::level_cell_iterator cell_dofs(
549 &cell_tria->get_triangulation(),
554 const auto mapping_q =
555 dynamic_cast<const MappingQ<dim, spacedim> *>(&mapping);
559 ((vector_describes_relative_displacement ||
560 (is_non_artificial_cell == false)) &&
561 ((mapping_q != nullptr &&
562 this->get_degree() == mapping_q->get_degree()) ==
565 (is_non_artificial_cell == true && interpolation_of_values_is_needed) )
570 auto &fe_values = fe_values_all.get();
571 if (fe_values.get() == nullptr)
573 const QGaussLobatto<dim> quadrature_gl(this->polynomial_degree +
576 std::vector<Point<dim>> quadrature_points;
578 FETools::hierarchic_to_lexicographic_numbering<dim>(
579 this->polynomial_degree))
580 quadrature_points.push_back(quadrature_gl.point(i));
581 const Quadrature<dim> quadrature(quadrature_points);
583 fe_values = std::make_unique<FEValues<dim, spacedim>>(
585 interpolation_of_values_is_needed ?
587 static_cast<const FiniteElement<dim, spacedim> &>(fe_nothing),
589 update_quadrature_points | update_values);
592 if (interpolation_of_values_is_needed)
593 fe_values->reinit(cell_dofs);
595 fe_values->reinit(cell_tria);
603 if (vector_describes_relative_displacement ||
604 (is_non_artificial_cell ==
false))
606 if (mapping_q !=
nullptr &&
607 this->get_degree() == mapping_q->get_degree())
608 result = mapping_q->compute_mapping_support_points(cell_tria);
610 result = fe_values_all.
get()->get_quadrature_points();
615 if (is_non_artificial_cell ==
false)
625 if (interpolation_of_values_is_needed ==
false)
629 std::vector<types::global_dof_index> dof_indices(
631 cell_dofs->get_mg_dof_indices(dof_indices);
633 for (
unsigned int i = 0; i < dof_indices.size(); ++i)
640 if (vector_describes_relative_displacement)
641 result[
id.second][
id.first] +=
642 vectors_ghosted[cell_tria->level()](dof_indices[i]);
644 result[
id.second][
id.first] =
645 vectors_ghosted[cell_tria->level()](dof_indices[i]);
650 if (vector_describes_relative_displacement)
651 result[lexicographic_to_hierarchic_numbering[
id.second]]
653 vectors_ghosted[cell_tria->level()](dof_indices[i]);
655 result[lexicographic_to_hierarchic_numbering[
id.second]]
657 vectors_ghosted[cell_tria->level()](dof_indices[i]);
667 auto &fe_values = fe_values_all.
get();
669 std::vector<types::global_dof_index> dof_indices(
671 cell_dofs->get_mg_dof_indices(dof_indices);
673 std::vector<typename VectorType::value_type> dof_values(
677 dof_values[i] = vectors_ghosted[cell_tria->level()](dof_indices[i]);
679 for (
unsigned int c = 0; c < spacedim; ++c)
681 for (
unsigned int q = 0; q < fe_values->n_quadrature_points; ++q)
682 if (vector_describes_relative_displacement ==
false && i == 0)
684 dof_values[i] * fe_values->shape_value_component(i, q, c);
687 dof_values[i] * fe_values->shape_value_component(i, q, c);
693 uses_level_info =
true;
698template <
int dim,
int spacedim>
702 if (support_point_cache.get() !=
nullptr)
703 return sizeof(*this) +
706 return sizeof(*this);
711template <
int dim,
int spacedim>
712std::vector<Point<spacedim>>
716 Assert(support_point_cache.get() !=
nullptr,
717 ExcMessage(
"Must call MappingQCache::initialize() before "
718 "using it or after mesh has changed!"));
723 AssertIndexRange(cell->index(), (*support_point_cache)[cell->level()].size());
724 return (*support_point_cache)[cell->level()][cell->index()];
729template <
int dim,
int spacedim>
730boost::container::small_vector<Point<spacedim>,
735 Assert(support_point_cache.get() !=
nullptr,
736 ExcMessage(
"Must call MappingQCache::initialize() before "
737 "using it or after mesh has changed!"));
742 AssertIndexRange(cell->index(), (*support_point_cache)[cell->level()].size());
743 const auto ptr = (*support_point_cache)[cell->level()][cell->index()].begin();
744 return boost::container::small_vector<Point<spacedim>,
746 ptr, ptr + cell->n_vertices());
752#include "mapping_q_cache.inst"
const hp::FECollection< dim, spacedim > & get_fe_collection() const
const FiniteElement< dim, spacedim > & get_fe(const types::fe_index index=0) const
const IndexSet & locally_owned_mg_dofs(const unsigned int level) const
const Triangulation< dim, spacedim > & get_triangulation() const
const IndexSet & locally_owned_dofs() const
MPI_Comm get_communicator() const
const unsigned int degree
unsigned int n_dofs_per_cell() const
virtual const FiniteElement< dim, spacedim > & base_element(const unsigned int index) const
std::pair< unsigned int, unsigned int > system_to_component_index(const unsigned int index) const
unsigned int element_multiplicity(const unsigned int index) const
unsigned int n_base_elements() const
const unsigned int n_components
virtual RangeNumberType value(const Point< dim > &p, const unsigned int component=0) const
void import_elements(const ::Vector< Number > &vec, VectorOperation::values operation, const std::shared_ptr< const Utilities::MPI::CommunicationPatternBase > &communication_pattern={})
virtual void reinit(const size_type size, const bool omit_zeroing_entries=false)
void update_ghost_values() const
void import_elements(const Vector< Number, MemorySpace2 > &src, VectorOperation::values operation)
void reinit(const size_type size, const bool omit_zeroing_entries=false)
unsigned int max_level() const
unsigned int min_level() const
std::size_t memory_consumption() const
virtual boost::container::small_vector< Point< spacedim >, GeometryInfo< dim >::vertices_per_cell > get_vertices(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const override
virtual bool preserves_vertex_locations() const override
virtual std::vector< Point< spacedim > > compute_mapping_support_points(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const override
virtual std::unique_ptr< Mapping< dim, spacedim > > clone() const override
void initialize(const Mapping< dim, spacedim > &mapping, const Triangulation< dim, spacedim > &triangulation)
virtual std::vector< Point< spacedim > > compute_mapping_support_points(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const
friend class MappingQCache
Abstract base class for mapping classes.
static unsigned int n_threads()
A class that provides a separate storage location on each thread that accesses the object.
cell_iterator begin(const unsigned int level=0) const
unsigned int n_levels() const
cell_iterator end() const
unsigned int n_raw_cells(const unsigned int level) const
virtual unsigned int n_global_levels() const
unsigned int size() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
@ update_quadrature_points
Transformed quadrature points.
std::enable_if_t< std::is_fundamental_v< T >, std::size_t > memory_consumption(const T &t)
constexpr T pow(const T base, const int iexp)
std::vector< Integer > invert_permutation(const std::vector< Integer > &permutation)
void run(const std::vector< std::vector< Iterator > > &colored_iterators, Worker worker, Copier copier, const ScratchData &sample_scratch_data, const CopyData &sample_copy_data, const unsigned int queue_length=2 *MultithreadInfo::n_threads(), const unsigned int chunk_size=8)
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation