Loading [MathJax]/extensions/TeX/AMSsymbols.js
 deal.II version GIT relicensing-2968-g5f01c80b02 2025-03-29 13:10:00+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
mapping_q_cache.cc
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2019 - 2024 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
18
20
21#include <deal.II/fe/fe_dgq.h>
23#include <deal.II/fe/fe_q.h>
24#include <deal.II/fe/fe_tools.h>
27
31
32#include <functional>
33
35
36template <int dim, int spacedim>
38 const unsigned int polynomial_degree)
39 : MappingQ<dim, spacedim>(polynomial_degree)
40 , uses_level_info(false)
41{}
42
43
44
45template <int dim, int spacedim>
47 const MappingQCache<dim, spacedim> &mapping)
48 : MappingQ<dim, spacedim>(mapping)
49 , support_point_cache(mapping.support_point_cache)
50 , uses_level_info(mapping.uses_level_info)
51{}
52
53
54
55template <int dim, int spacedim>
57{
58 // When this object goes out of scope, we want the cache to get cleared and
59 // free its memory before the signal is disconnected in order to not work on
60 // invalid memory that has been left back by freeing an object of this
61 // class.
62 support_point_cache.reset();
63 clear_signal.disconnect();
64}
65
66
67
68template <int dim, int spacedim>
69std::unique_ptr<Mapping<dim, spacedim>>
71{
72 return std::make_unique<MappingQCache<dim, spacedim>>(*this);
73}
74
75
76
77template <int dim, int spacedim>
78bool
83
84
85
86template <int dim, int spacedim>
87void
89 const Mapping<dim, spacedim> &mapping,
91{
92 // FE and FEValues in the case they are needed
95 fe_values_all;
96
97 this->initialize(
98 triangulation,
99 [&](const typename Triangulation<dim, spacedim>::cell_iterator &cell) {
100 const auto mapping_q =
101 dynamic_cast<const MappingQ<dim, spacedim> *>(&mapping);
102 if (mapping_q != nullptr && this->get_degree() == mapping_q->get_degree())
103 {
104 return mapping_q->compute_mapping_support_points(cell);
105 }
106 else
107 {
108 // get FEValues (thread-safe); in the case that this thread has not
109 // created a an FEValues object yet, this helper-function also
110 // creates one with the right quadrature rule
111 auto &fe_values = fe_values_all.get();
112 if (fe_values.get() == nullptr)
113 {
114 const QGaussLobatto<dim> quadrature_gl(this->polynomial_degree +
115 1);
116
117 std::vector<Point<dim>> quadrature_points;
118 for (const auto i :
119 FETools::hierarchic_to_lexicographic_numbering<dim>(
120 this->polynomial_degree))
121 quadrature_points.push_back(quadrature_gl.point(i));
122 const Quadrature<dim> quadrature(quadrature_points);
123
124 fe_values = std::make_unique<FEValues<dim, spacedim>>(
125 mapping, fe, quadrature, update_quadrature_points);
126 }
127
128 fe_values->reinit(cell);
129 return fe_values->get_quadrature_points();
130 }
131 });
132}
133
134
135
136template <int dim, int spacedim>
137void
140 const std::function<std::vector<Point<spacedim>>(
142 &compute_points_on_cell)
143{
144 clear_signal.disconnect();
145 clear_signal = triangulation.signals.any_change.connect(
146 [&]() -> void { this->support_point_cache.reset(); });
147
148 support_point_cache =
149 std::make_shared<std::vector<std::vector<std::vector<Point<spacedim>>>>>(
150 triangulation.n_levels());
151 for (unsigned int l = 0; l < triangulation.n_levels(); ++l)
152 (*support_point_cache)[l].resize(triangulation.n_raw_cells(l));
153
155 triangulation.begin(),
156 triangulation.end(),
157 [&](const typename Triangulation<dim, spacedim>::cell_iterator &cell,
158 void *,
159 void *) {
160 (*support_point_cache)[cell->level()][cell->index()] =
161 compute_points_on_cell(cell);
162 // Do not use `this` in Assert because nvcc when using C++20 assumes that
163 // `this` is an integer and we get the following error: invalid type
164 // argument of unary '*' (have 'int')
165 [[maybe_unused]] const unsigned int d = this->get_degree() + 1;
166 AssertDimension(
167 (*support_point_cache)[cell->level()][cell->index()].size(),
168 Utilities::pow(d, dim));
169 },
170 /* copier */ std::function<void(void *)>(),
171 /* scratch_data */ nullptr,
172 /* copy_data */ nullptr,
174 /* chunk_size = */ 1);
175
176 uses_level_info = true;
177}
178
179
180
181template <int dim, int spacedim>
182void
184 const Mapping<dim, spacedim> &mapping,
186 const std::function<Point<spacedim>(
188 const Point<spacedim> &)> &transformation_function,
189 const bool function_describes_relative_displacement)
190{
191 // FE and FEValues in the case they are needed
194 fe_values_all;
195
196 this->initialize(
197 tria,
198 [&](const typename Triangulation<dim, spacedim>::cell_iterator &cell) {
199 std::vector<Point<spacedim>> points;
200
201 const auto mapping_q =
202 dynamic_cast<const MappingQ<dim, spacedim> *>(&mapping);
203
204 if (mapping_q != nullptr && this->get_degree() == mapping_q->get_degree())
205 {
206 points = mapping_q->compute_mapping_support_points(cell);
207 }
208 else
209 {
210 // get FEValues (thread-safe); in the case that this thread has not
211 // created a an FEValues object yet, this helper-function also
212 // creates one with the right quadrature rule
213 auto &fe_values = fe_values_all.get();
214 if (fe_values.get() == nullptr)
215 {
216 const QGaussLobatto<dim> quadrature_gl(this->polynomial_degree +
217 1);
218
219 std::vector<Point<dim>> quadrature_points;
220 for (const auto i :
221 FETools::hierarchic_to_lexicographic_numbering<dim>(
222 this->polynomial_degree))
223 quadrature_points.push_back(quadrature_gl.point(i));
224 const Quadrature<dim> quadrature(quadrature_points);
225
226 fe_values = std::make_unique<FEValues<dim, spacedim>>(
227 mapping, fe, quadrature, update_quadrature_points);
228 }
229
230 fe_values->reinit(cell);
231 points = fe_values->get_quadrature_points();
232 }
233
234 for (auto &p : points)
235 if (function_describes_relative_displacement)
236 p += transformation_function(cell, p);
237 else
238 p = transformation_function(cell, p);
239
240 return points;
241 });
242
243 uses_level_info = true;
244}
245
246
247
248template <int dim, int spacedim>
249void
251 const Mapping<dim, spacedim> &mapping,
253 const Function<spacedim> &transformation_function,
254 const bool function_describes_relative_displacement)
255{
256 AssertDimension(transformation_function.n_components, spacedim);
257
258 this->initialize(
259 mapping,
260 tria,
261 [&](const auto &, const auto &point) {
262 Point<spacedim> new_point;
263 for (unsigned int c = 0; c < spacedim; ++c)
264 new_point[c] = transformation_function.value(point, c);
265 return new_point;
266 },
267 function_describes_relative_displacement);
268
269 uses_level_info = true;
270}
271
272
273
274namespace
275{
276 template <typename VectorType>
277 void
278 copy_locally_owned_data_from(
279 const VectorType &vector,
281 &vector_ghosted)
282 {
284 temp.reinit(vector.locally_owned_elements());
286 vector_ghosted.import_elements(temp, VectorOperation::insert);
287 }
288} // namespace
289
290
291
292template <int dim, int spacedim>
293template <typename VectorType>
294void
296 const Mapping<dim, spacedim> &mapping,
297 const DoFHandler<dim, spacedim> &dof_handler,
298 const VectorType &vector,
299 const bool vector_describes_relative_displacement)
300{
301 AssertDimension(dof_handler.get_fe_collection().size(), 1);
302 const FiniteElement<dim, spacedim> &fe = dof_handler.get_fe();
304 AssertDimension(fe.element_multiplicity(0), spacedim);
305
306 const unsigned int is_fe_q =
307 dynamic_cast<const FE_Q<dim, spacedim> *>(&fe.base_element(0)) != nullptr;
308 const unsigned int is_fe_dgq =
309 dynamic_cast<const FE_DGQ<dim, spacedim> *>(&fe.base_element(0)) != nullptr;
310
311 const auto lexicographic_to_hierarchic_numbering =
313 FETools::hierarchic_to_lexicographic_numbering<spacedim>(
314 this->get_degree()));
315
316 // Step 1: copy global vector so that the ghost values are such that the
317 // cache can be set up for all ghost cells
319 vector_ghosted;
320 const IndexSet locally_relevant_dofs =
322 vector_ghosted.reinit(dof_handler.locally_owned_dofs(),
323 locally_relevant_dofs,
324 dof_handler.get_mpi_communicator());
325 copy_locally_owned_data_from(vector, vector_ghosted);
326 vector_ghosted.update_ghost_values();
327
328 // FE and FEValues in the case they are needed
329 FE_Nothing<dim, spacedim> fe_nothing;
331 fe_values_all;
332
333 // Interpolation of values is needed if we cannot just read off locations
334 // from the solution vectors (as in the case of FE_Q and FE_DGQ with the
335 // same polynomial degree as this class has).
336 const bool interpolation_of_values_is_needed =
337 ((is_fe_q || is_fe_dgq) && fe.degree == this->get_degree()) == false;
338
339 // Step 2: loop over all cells
340 this->initialize(
341 dof_handler.get_triangulation(),
342 [&](const typename Triangulation<dim, spacedim>::cell_iterator &cell_tria)
343 -> std::vector<Point<spacedim>> {
344 const bool is_active_non_artificial_cell =
345 (cell_tria->is_active() == true) &&
346 (cell_tria->is_artificial() == false);
347
348 const typename DoFHandler<dim, spacedim>::cell_iterator cell_dofs(
349 &cell_tria->get_triangulation(),
350 cell_tria->level(),
351 cell_tria->index(),
352 &dof_handler);
353
354 const auto mapping_q =
355 dynamic_cast<const MappingQ<dim, spacedim> *>(&mapping);
356
357 // Step 2a) set up and reinit FEValues (if needed)
358 if (
359 ((vector_describes_relative_displacement ||
360 (is_active_non_artificial_cell == false)) &&
361 ((mapping_q != nullptr &&
362 this->get_degree() == mapping_q->get_degree()) ==
363 false)) /*condition 1: points need to be computed via FEValues*/
364 ||
365 (is_active_non_artificial_cell && interpolation_of_values_is_needed) /*condition 2: interpolation of values is needed*/)
366 {
367 // get FEValues (thread-safe); in the case that this thread has
368 // not created a an FEValues object yet, this helper-function also
369 // creates one with the right quadrature rule
370 auto &fe_values = fe_values_all.get();
371 if (fe_values.get() == nullptr)
372 {
373 const QGaussLobatto<dim> quadrature_gl(this->polynomial_degree +
374 1);
375
376 std::vector<Point<dim>> quadrature_points;
377 for (const auto i :
378 FETools::hierarchic_to_lexicographic_numbering<dim>(
379 this->polynomial_degree))
380 quadrature_points.push_back(quadrature_gl.point(i));
381 const Quadrature<dim> quadrature(quadrature_points);
382
383 fe_values = std::make_unique<FEValues<dim, spacedim>>(
384 mapping,
385 interpolation_of_values_is_needed ?
386 fe :
387 static_cast<const FiniteElement<dim, spacedim> &>(fe_nothing),
388 quadrature,
389 update_quadrature_points | update_values);
390 }
391
392 if (interpolation_of_values_is_needed)
393 fe_values->reinit(cell_dofs);
394 else
395 fe_values->reinit(cell_tria);
396 }
397
398 std::vector<Point<spacedim>> result;
399
400 // Step 2b) read of quadrature points in the relative displacement case
401 // note: we also take this path for non-active or artificial cells so that
402 // these cells are filled with some useful data
403 if (vector_describes_relative_displacement ||
404 is_active_non_artificial_cell == false)
405 {
406 if (mapping_q != nullptr &&
407 this->get_degree() == mapping_q->get_degree())
408 result = mapping_q->compute_mapping_support_points(cell_tria);
409 else
410 result = fe_values_all.get()->get_quadrature_points();
411
412 // for non-active or artificial cells we are done here and return
413 // the absolute positions, since the provided vector cannot contain
414 // any useful information for these cells
415 if (is_active_non_artificial_cell == false)
416 return result;
417 }
418 else
419 {
420 result.resize(
421 Utilities::pow<unsigned int>(this->get_degree() + 1, dim));
422 }
423
424 // Step 2c) read global vector and adjust points accordingly
425 if (interpolation_of_values_is_needed == false)
426 {
427 // case 1: FE_Q or FE_DGQ with same degree as this class has; this
428 // is the simple case since no interpolation is needed
429 std::vector<types::global_dof_index> dof_indices(
430 fe.n_dofs_per_cell());
431 cell_dofs->get_dof_indices(dof_indices);
432
433 for (unsigned int i = 0; i < dof_indices.size(); ++i)
434 {
435 const auto id = fe.system_to_component_index(i);
436
437 if (is_fe_q)
438 {
439 // case 1a: FE_Q
440 if (vector_describes_relative_displacement)
441 result[id.second][id.first] +=
442 vector_ghosted(dof_indices[i]);
443 else
444 result[id.second][id.first] =
445 vector_ghosted(dof_indices[i]);
446 }
447 else
448 {
449 // case 1b: FE_DGQ
450 if (vector_describes_relative_displacement)
451 result[lexicographic_to_hierarchic_numbering[id.second]]
452 [id.first] += vector_ghosted(dof_indices[i]);
453 else
454 result[lexicographic_to_hierarchic_numbering[id.second]]
455 [id.first] = vector_ghosted(dof_indices[i]);
456 }
457 }
458 }
459 else
460 {
461 // case 2: general case; interpolation is needed
462 // note: the following code could be optimized for tensor-product
463 // elements via application of sum factorization as is done on
464 // MatrixFree/FEEvaluation
465 auto &fe_values = fe_values_all.get();
466
467 std::vector<Vector<typename VectorType::value_type>> values(
468 fe_values->n_quadrature_points,
470
471 fe_values->get_function_values(vector_ghosted, values);
472
473 for (unsigned int q = 0; q < fe_values->n_quadrature_points; ++q)
474 for (unsigned int c = 0; c < spacedim; ++c)
475 if (vector_describes_relative_displacement)
476 result[q][c] += values[q][c];
477 else
478 result[q][c] = values[q][c];
479 }
480
481 return result;
482 });
483
484 uses_level_info = false;
485}
486
487
488
489template <int dim, int spacedim>
490template <typename VectorType>
491void
493 const Mapping<dim, spacedim> &mapping,
494 const DoFHandler<dim, spacedim> &dof_handler,
495 const MGLevelObject<VectorType> &vectors,
496 const bool vector_describes_relative_displacement)
497{
498 AssertDimension(dof_handler.get_fe_collection().size(), 1);
499 const FiniteElement<dim, spacedim> &fe = dof_handler.get_fe();
501 AssertDimension(fe.element_multiplicity(0), spacedim);
502 AssertDimension(0, vectors.min_level());
504 vectors.max_level());
505
506 const unsigned int is_fe_q =
507 dynamic_cast<const FE_Q<dim, spacedim> *>(&fe.base_element(0)) != nullptr;
508 const unsigned int is_fe_dgq =
509 dynamic_cast<const FE_DGQ<dim, spacedim> *>(&fe.base_element(0)) != nullptr;
510
511 const auto lexicographic_to_hierarchic_numbering =
513 FETools::hierarchic_to_lexicographic_numbering<spacedim>(
514 this->get_degree()));
515
516 // Step 1: copy global vector so that the ghost values are such that the
517 // cache can be set up for all ghost cells
520 vectors_ghosted(vectors.min_level(), vectors.max_level());
521
522 for (unsigned int l = vectors.min_level(); l <= vectors.max_level(); ++l)
523 {
524 const IndexSet locally_relevant_dofs =
526 vectors_ghosted[l].reinit(dof_handler.locally_owned_mg_dofs(l),
527 locally_relevant_dofs,
528 dof_handler.get_mpi_communicator());
529 copy_locally_owned_data_from(vectors[l], vectors_ghosted[l]);
530 vectors_ghosted[l].update_ghost_values();
531 }
532
533 // FE and FEValues in the case they are needed
534 FE_Nothing<dim, spacedim> fe_nothing;
536 fe_values_all;
537
538 // Interpolation of values is needed if we cannot just read off locations
539 // from the solution vectors (as in the case of FE_Q and FE_DGQ with the
540 // same polynomial degree as this class has).
541 const bool interpolation_of_values_is_needed =
542 ((is_fe_q || is_fe_dgq) && fe.degree == this->get_degree()) == false;
543
544 // Step 2: loop over all cells
545 this->initialize(
546 dof_handler.get_triangulation(),
547 [&](const typename Triangulation<dim, spacedim>::cell_iterator &cell_tria)
548 -> std::vector<Point<spacedim>> {
549 const bool is_non_artificial_cell =
550 cell_tria->level_subdomain_id() != numbers::artificial_subdomain_id;
551
552 const typename DoFHandler<dim, spacedim>::level_cell_iterator cell_dofs(
553 &cell_tria->get_triangulation(),
554 cell_tria->level(),
555 cell_tria->index(),
556 &dof_handler);
557
558 const auto mapping_q =
559 dynamic_cast<const MappingQ<dim, spacedim> *>(&mapping);
560
561 // Step 2a) set up and reinit FEValues (if needed)
562 if (
563 ((vector_describes_relative_displacement ||
564 (is_non_artificial_cell == false)) &&
565 ((mapping_q != nullptr &&
566 this->get_degree() == mapping_q->get_degree()) ==
567 false)) /*condition 1: points need to be computed via FEValues*/
568 ||
569 (is_non_artificial_cell == true && interpolation_of_values_is_needed) /*condition 2: interpolation of values is needed*/)
570 {
571 // get FEValues (thread-safe); in the case that this thread has
572 // not created a an FEValues object yet, this helper-function also
573 // creates one with the right quadrature rule
574 auto &fe_values = fe_values_all.get();
575 if (fe_values.get() == nullptr)
576 {
577 const QGaussLobatto<dim> quadrature_gl(this->polynomial_degree +
578 1);
579
580 std::vector<Point<dim>> quadrature_points;
581 for (const auto i :
582 FETools::hierarchic_to_lexicographic_numbering<dim>(
583 this->polynomial_degree))
584 quadrature_points.push_back(quadrature_gl.point(i));
585 const Quadrature<dim> quadrature(quadrature_points);
586
587 fe_values = std::make_unique<FEValues<dim, spacedim>>(
588 mapping,
589 interpolation_of_values_is_needed ?
590 fe :
591 static_cast<const FiniteElement<dim, spacedim> &>(fe_nothing),
592 quadrature,
593 update_quadrature_points | update_values);
594 }
595
596 if (interpolation_of_values_is_needed)
597 fe_values->reinit(cell_dofs);
598 else
599 fe_values->reinit(cell_tria);
600 }
601
602 std::vector<Point<spacedim>> result;
603
604 // Step 2b) read of quadrature points in the relative displacement case
605 // note: we also take this path for non-active or artificial cells so that
606 // these cells are filled with some useful data
607 if (vector_describes_relative_displacement ||
608 (is_non_artificial_cell == false))
609 {
610 if (mapping_q != nullptr &&
611 this->get_degree() == mapping_q->get_degree())
612 result = mapping_q->compute_mapping_support_points(cell_tria);
613 else
614 result = fe_values_all.get()->get_quadrature_points();
615
616 // for non-active or artificial cells we are done here and return
617 // the absolute positions, since the provided vector cannot contain
618 // any useful information for these cells
619 if (is_non_artificial_cell == false)
620 return result;
621 }
622 else
623 {
624 result.resize(
625 Utilities::pow<unsigned int>(this->get_degree() + 1, dim));
626 }
627
628 // Step 2c) read global vector and adjust points accordingly
629 if (interpolation_of_values_is_needed == false)
630 {
631 // case 1: FE_Q or FE_DGQ with same degree as this class has; this
632 // is the simple case since no interpolation is needed
633 std::vector<types::global_dof_index> dof_indices(
634 fe.n_dofs_per_cell());
635 cell_dofs->get_mg_dof_indices(dof_indices);
636
637 for (unsigned int i = 0; i < dof_indices.size(); ++i)
638 {
639 const auto id = fe.system_to_component_index(i);
640
641 if (is_fe_q)
642 {
643 // case 1a: FE_Q
644 if (vector_describes_relative_displacement)
645 result[id.second][id.first] +=
646 vectors_ghosted[cell_tria->level()](dof_indices[i]);
647 else
648 result[id.second][id.first] =
649 vectors_ghosted[cell_tria->level()](dof_indices[i]);
650 }
651 else
652 {
653 // case 1b: FE_DGQ
654 if (vector_describes_relative_displacement)
655 result[lexicographic_to_hierarchic_numbering[id.second]]
656 [id.first] +=
657 vectors_ghosted[cell_tria->level()](dof_indices[i]);
658 else
659 result[lexicographic_to_hierarchic_numbering[id.second]]
660 [id.first] =
661 vectors_ghosted[cell_tria->level()](dof_indices[i]);
662 }
663 }
664 }
665 else
666 {
667 // case 2: general case; interpolation is needed
668 // note: the following code could be optimized for tensor-product
669 // elements via application of sum factorization as is done on
670 // MatrixFree/FEEvaluation
671 auto &fe_values = fe_values_all.get();
672
673 std::vector<types::global_dof_index> dof_indices(
674 fe.n_dofs_per_cell());
675 cell_dofs->get_mg_dof_indices(dof_indices);
676
677 std::vector<typename VectorType::value_type> dof_values(
678 fe.n_dofs_per_cell());
679
680 for (unsigned int i = 0; i < fe.n_dofs_per_cell(); ++i)
681 dof_values[i] = vectors_ghosted[cell_tria->level()](dof_indices[i]);
682
683 for (unsigned int c = 0; c < spacedim; ++c)
684 for (unsigned int i = 0; i < fe.n_dofs_per_cell(); ++i)
685 for (unsigned int q = 0; q < fe_values->n_quadrature_points; ++q)
686 if (vector_describes_relative_displacement == false && i == 0)
687 result[q][c] =
688 dof_values[i] * fe_values->shape_value_component(i, q, c);
689 else
690 result[q][c] +=
691 dof_values[i] * fe_values->shape_value_component(i, q, c);
692 }
693
694 return result;
695 });
696
697 uses_level_info = true;
698}
699
700
701
702template <int dim, int spacedim>
703std::size_t
705{
706 if (support_point_cache.get() != nullptr)
707 return sizeof(*this) +
708 MemoryConsumption::memory_consumption(*support_point_cache);
709 else
710 return sizeof(*this);
711}
712
713
714
715template <int dim, int spacedim>
716std::vector<Point<spacedim>>
718 const typename Triangulation<dim, spacedim>::cell_iterator &cell) const
719{
720 Assert(support_point_cache.get() != nullptr,
721 ExcMessage("Must call MappingQCache::initialize() before "
722 "using it or after mesh has changed!"));
723
724 Assert(uses_level_info || cell->is_active(), ExcInternalError());
725
726 AssertIndexRange(cell->level(), support_point_cache->size());
727 AssertIndexRange(cell->index(), (*support_point_cache)[cell->level()].size());
728 return (*support_point_cache)[cell->level()][cell->index()];
729}
730
731
732
733template <int dim, int spacedim>
734boost::container::small_vector<Point<spacedim>,
735#ifndef _MSC_VER
736 ReferenceCells::max_n_vertices<dim>()
737#else
739#endif
740 >
742 const typename Triangulation<dim, spacedim>::cell_iterator &cell) const
743{
744 Assert(support_point_cache.get() != nullptr,
745 ExcMessage("Must call MappingQCache::initialize() before "
746 "using it or after mesh has changed!"));
747
748 Assert(uses_level_info || cell->is_active(), ExcInternalError());
749
750 AssertIndexRange(cell->level(), support_point_cache->size());
751 AssertIndexRange(cell->index(), (*support_point_cache)[cell->level()].size());
752 const auto ptr = (*support_point_cache)[cell->level()][cell->index()].begin();
753 return boost::container::small_vector<Point<spacedim>,
754#ifndef _MSC_VER
755 ReferenceCells::max_n_vertices<dim>()
756#else
758#endif
759 >(ptr, ptr + cell->n_vertices());
760}
761
762
763
764//--------------------------- Explicit instantiations -----------------------
765#include "fe/mapping_q_cache.inst"
766
767
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_mpi_communicator() const
Definition fe_q.h:554
const unsigned int degree
Definition fe_data.h:452
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
Definition function.h:164
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 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 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 boost::container::small_vector< Point< spacedim >, ReferenceCells::max_n_vertices< dim >() > get_vertices(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
Definition mapping_q.h:672
Abstract base class for mapping classes.
Definition mapping.h:320
static unsigned int n_threads()
Definition point.h:113
A class that provides a separate storage location on each thread that accesses the object.
virtual unsigned int n_global_levels() const
unsigned int size() const
Definition collection.h:316
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:40
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:41
#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.
IndexSet extract_locally_relevant_dofs(const DoFHandler< dim, spacedim > &dof_handler)
IndexSet extract_locally_relevant_level_dofs(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int level)
std::enable_if_t< std::is_fundamental_v< T >, std::size_t > memory_consumption(const T &t)
std::vector< Integer > invert_permutation(const std::vector< Integer > &permutation)
Definition utilities.h:1700
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