deal.II version 9.7.0
\(\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\}}\)
Loading...
Searching...
No Matches
vector_tools_evaluate.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2021 - 2025 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
15
16#ifndef dealii_vector_tools_evaluation_h
17#define dealii_vector_tools_evaluation_h
18
19#include <deal.II/base/config.h>
20
22
24
26
28#include <deal.II/lac/vector.h>
29
31
33
34namespace VectorTools
35{
40 {
45 {
49 avg = 0,
55 max = 1,
61 min = 2,
66 };
67 } // namespace EvaluationFlags
68
139 template <int n_components,
140 template <int, int>
141 class MeshType,
142 int dim,
143 int spacedim,
144 typename VectorType>
147 concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
148 std::vector<
149 typename FEPointEvaluation<n_components,
150 dim,
151 spacedim,
152 typename VectorType::value_type>::
153 value_type> point_values(const Mapping<dim> &mapping,
154 const MeshType<dim, spacedim> &mesh,
155 const VectorType &vector,
156 const std::vector<Point<spacedim>>
157 &evaluation_points,
158 Utilities::MPI::RemotePointEvaluation<dim,
159 spacedim>
160 &cache,
161 const EvaluationFlags::EvaluationFlags flags =
162 EvaluationFlags::avg,
163 const unsigned int first_selected_component = 0);
164
180 template <int n_components,
181 template <int, int>
182 class MeshType,
183 int dim,
184 int spacedim,
185 typename VectorType>
187 (concepts::is_dealii_vector_type<VectorType> &&
188 concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
189 std::vector<
190 typename FEPointEvaluation<n_components,
191 dim,
192 spacedim,
193 typename VectorType::value_type>::
194 value_type> point_values(const Utilities::MPI::
195 RemotePointEvaluation<dim, spacedim> &cache,
196 const MeshType<dim, spacedim> &mesh,
197 const VectorType &vector,
198 const EvaluationFlags::EvaluationFlags flags =
199 EvaluationFlags::avg,
200 const unsigned int first_selected_component = 0);
201
215 template <int n_components,
216 template <int, int>
217 class MeshType,
218 int dim,
219 int spacedim,
220 typename VectorType>
222 (concepts::is_dealii_vector_type<VectorType> &&
223 concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
224 std::vector<
225 typename FEPointEvaluation<n_components,
226 dim,
227 spacedim,
228 typename VectorType::value_type>::
229 gradient_type> point_gradients(const Mapping<dim> &mapping,
230 const MeshType<dim, spacedim> &mesh,
231 const VectorType &vector,
232 const std::vector<Point<spacedim>>
233 &evaluation_points,
234 Utilities::MPI::RemotePointEvaluation<
235 dim,
236 spacedim> &cache,
238 flags = EvaluationFlags::avg,
239 const unsigned int
240 first_selected_component = 0);
241
256 template <int n_components,
257 template <int, int>
258 class MeshType,
259 int dim,
260 int spacedim,
261 typename VectorType>
263 (concepts::is_dealii_vector_type<VectorType> &&
264 concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
265 std::vector<
266 typename FEPointEvaluation<n_components,
267 dim,
268 spacedim,
269 typename VectorType::value_type>::
270 gradient_type> point_gradients(const Utilities::MPI::
271 RemotePointEvaluation<dim, spacedim>
272 &cache,
273 const MeshType<dim, spacedim> &mesh,
274 const VectorType &vector,
276 flags = EvaluationFlags::avg,
277 const unsigned int
278 first_selected_component = 0);
279
280
281
282 // inlined functions
283
284
285#ifndef DOXYGEN
286 template <int n_components,
287 template <int, int>
288 class MeshType,
289 int dim,
290 int spacedim,
291 typename VectorType>
294 concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
295 inline std::vector<
296 typename FEPointEvaluation<n_components,
297 dim,
298 spacedim,
299 typename VectorType::value_type>::
300 value_type> point_values(const Mapping<dim> &mapping,
301 const MeshType<dim, spacedim> &mesh,
302 const VectorType &vector,
303 const std::vector<Point<spacedim>>
304 &evaluation_points,
305 Utilities::MPI::RemotePointEvaluation<dim,
306 spacedim>
307 &cache,
308 const EvaluationFlags::EvaluationFlags flags,
309 const unsigned int first_selected_component)
310 {
311 cache.reinit(evaluation_points, mesh.get_triangulation(), mapping);
312
314 cache, mesh, vector, flags, first_selected_component);
315 }
316
317
318
319 template <int n_components,
320 template <int, int>
321 class MeshType,
322 int dim,
323 int spacedim,
324 typename VectorType>
327 concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
328 inline std::vector<
329 typename FEPointEvaluation<n_components,
330 dim,
331 spacedim,
332 typename VectorType::value_type>::
333 gradient_type> point_gradients(const Mapping<dim> &mapping,
334 const MeshType<dim, spacedim> &mesh,
335 const VectorType &vector,
336 const std::vector<Point<spacedim>>
337 &evaluation_points,
338 Utilities::MPI::RemotePointEvaluation<
339 dim,
340 spacedim> &cache,
342 flags,
343 const unsigned int
344 first_selected_component)
345 {
346 cache.reinit(evaluation_points, mesh.get_triangulation(), mapping);
347
349 cache, mesh, vector, flags, first_selected_component);
350 }
351
352
353
354 namespace internal
355 {
359 template <typename T>
360 T
362 const ArrayView<const T> &values)
363 {
364 switch (flags)
365 {
366 case EvaluationFlags::avg:
367 {
368 return std::accumulate(values.begin(), values.end(), T{}) /
369 (T(1.0) * values.size());
370 }
371 case EvaluationFlags::max:
372 return *std::max_element(values.begin(), values.end());
373 case EvaluationFlags::min:
374 return *std::min_element(values.begin(), values.end());
375 case EvaluationFlags::insert:
376 return values[0];
377 default:
379 return values[0];
380 }
381 }
382
383
384
388 template <int rank, int dim, typename Number>
389 Tensor<rank, dim, Number>
391 const ArrayView<const Tensor<rank, dim, Number>> &values)
392 {
393 switch (flags)
394 {
395 case EvaluationFlags::avg:
396 {
397 return std::accumulate(values.begin(),
398 values.end(),
399 Tensor<rank, dim, Number>{}) /
400 (Number(1.0) * values.size());
401 }
402 case EvaluationFlags::insert:
403 return values[0];
404 default:
406 return values[0];
407 }
408 }
409
410
411
416 template <int n_components, int rank, int dim, typename Number>
417 Tensor<1, n_components, Tensor<rank, dim, Number>>
418 reduce(
420 const ArrayView<const Tensor<1, n_components, Tensor<rank, dim, Number>>>
421 &values)
422 {
423 switch (flags)
424 {
425 case EvaluationFlags::avg:
426 {
427 Tensor<1, n_components, Tensor<rank, dim, Number>> temp;
428
429 for (unsigned int j = 0; j < values.size(); ++j)
430 for (unsigned int i = 0; i < n_components; ++i)
431 temp[i] = temp[i] + values[j][i];
432
433 for (unsigned int i = 0; i < n_components; ++i)
434 temp[i] /= Number(values.size());
435
436 return temp;
437 }
438 case EvaluationFlags::insert:
439 return values[0];
440 default:
442 return values[0];
443 }
444 }
445
446
447
448 template <int n_components,
449 int dim,
450 int spacedim,
451 typename VectorType,
452 typename value_type>
453 void
454 process_cell(
455 const unsigned int i,
456 const typename Utilities::MPI::RemotePointEvaluation<dim,
457 spacedim>::CellData
458 &cell_data,
459 const Utilities::MPI::RemotePointEvaluation<dim, spacedim> &cache,
460 const DoFHandler<dim, spacedim> &dof_handler,
461 const VectorType &vector,
462 const UpdateFlags update_flags,
463 const ::EvaluationFlags::EvaluationFlags evaluation_flags,
464 const unsigned int first_selected_component,
465 const std::function<
466 value_type(const FEPointEvaluation<n_components,
467 dim,
468 spacedim,
469 typename VectorType::value_type> &,
470 const unsigned int &)> process_quadrature_point,
471 const ArrayView<value_type> &values,
472 std::vector<typename VectorType::value_type> &solution_values,
473 std::vector<
474 std::unique_ptr<FEPointEvaluation<n_components,
475 dim,
476 spacedim,
477 typename VectorType::value_type>>>
478 &evaluators)
479 {
480 if (evaluators.empty())
481 evaluators.resize(dof_handler.get_fe_collection().size());
482
484 &cache.get_triangulation(),
485 cell_data.cells[i].first,
486 cell_data.cells[i].second,
487 &dof_handler};
488
489 const ArrayView<const Point<dim>> unit_points(
490 cell_data.reference_point_values.data() +
491 cell_data.reference_point_ptrs[i],
492 cell_data.reference_point_ptrs[i + 1] -
493 cell_data.reference_point_ptrs[i]);
494
495 solution_values.resize(
496 dof_handler.get_fe(cell->active_fe_index()).n_dofs_per_cell());
497 cell->get_dof_values(vector,
498 solution_values.begin(),
499 solution_values.end());
500
501 if (evaluators[cell->active_fe_index()] == nullptr)
502 evaluators[cell->active_fe_index()] =
503 std::make_unique<FEPointEvaluation<n_components,
504 dim,
505 spacedim,
506 typename VectorType::value_type>>(
507 cache.get_mapping(),
508 cell->get_fe(),
509 update_flags,
510 first_selected_component);
511 auto &evaluator = *evaluators[cell->active_fe_index()];
512
513 evaluator.reinit(cell, unit_points);
514 evaluator.evaluate(solution_values, evaluation_flags);
515
516 for (unsigned int q = 0; q < unit_points.size(); ++q)
517 values[q + cell_data.reference_point_ptrs[i]] =
518 process_quadrature_point(evaluator, q);
519 }
520
521
522
523 template <int dim, int spacedim, typename Number>
524 Number
525 get_value(
526 const Triangulation<dim, spacedim> &tria,
527 const Vector<Number> &vector,
529 {
530 AssertDimension(tria.n_active_cells(), vector.size());
531 return vector[cell->active_cell_index()];
532 }
533
534
535
536 template <int dim, int spacedim, typename Number>
537 Number
538 get_value(
539 const Triangulation<dim, spacedim> &tria,
540 const LinearAlgebra::distributed::Vector<Number> &vector,
542 {
543 const auto distributed_tria =
544 dynamic_cast<const parallel::TriangulationBase<dim, spacedim> *>(&tria);
545
546 const bool use_distributed_path =
547 (distributed_tria == nullptr) ?
548 false :
549 (vector.get_partitioner().get() ==
550 distributed_tria->global_active_cell_index_partitioner()
551 .lock()
552 .get());
553
554 if (use_distributed_path)
555 {
556 return vector[cell->global_active_cell_index()];
557 }
558 else
559 {
561 return vector[cell->active_cell_index()];
562 }
563 }
564
565
566
567 template <typename Number, typename Number2>
568 void
569 set_value(Number &dst, const Number2 &src)
570 {
571 dst = src;
572 }
573
574
575
576 template <typename Number, int rank, int dim, typename Number2>
577 void
578 set_value(Tensor<rank, dim, Number> &, const Number2 &)
579 {
580 Assert(false,
582 "A cell-data vector can only have a single component."));
583 }
584
585
586
587 template <int n_components,
588 int dim,
589 int spacedim,
590 typename VectorType,
591 typename value_type>
592 void
593 process_cell(
594 const unsigned int i,
595 const typename Utilities::MPI::RemotePointEvaluation<dim,
596 spacedim>::CellData
597 &cell_data,
598 const Utilities::MPI::RemotePointEvaluation<dim, spacedim> &,
599 const Triangulation<dim, spacedim> &triangulation,
600 const VectorType &vector,
601 const UpdateFlags,
602 const ::EvaluationFlags::EvaluationFlags evaluation_flags,
603 const unsigned int first_selected_component,
604 const std::function<
605 value_type(const FEPointEvaluation<n_components,
606 dim,
607 spacedim,
608 typename VectorType::value_type> &,
609 const unsigned int &)>,
610 const ArrayView<value_type> &values,
611 std::vector<typename VectorType::value_type> &,
612 std::vector<
613 std::unique_ptr<FEPointEvaluation<n_components,
614 dim,
615 spacedim,
616 typename VectorType::value_type>>> &)
617 {
618 Assert(n_components == 1 && first_selected_component == 0,
620 "A cell-data vector can only have a single component."));
621
622 Assert(evaluation_flags ==
624 ExcMessage("For cell-data vectors, only values can be queried."));
625
627 &triangulation, cell_data.cells[i].first, cell_data.cells[i].second};
628
629 const auto value = get_value(triangulation, vector, cell);
630
631 for (unsigned int q = cell_data.reference_point_ptrs[i];
632 q < cell_data.reference_point_ptrs[i + 1];
633 ++q)
634 set_value(values[q], value);
635 }
636
637
638
639 template <int n_components,
640 int dim,
641 int spacedim,
642 typename MeshType,
643 typename VectorType,
644 typename value_type>
646 concepts::is_dealii_vector_type<VectorType>
647 &&concepts::is_triangulation_or_dof_handler<MeshType>)
648 inline std::vector<value_type> evaluate_at_points(
649 const Utilities::MPI::RemotePointEvaluation<dim, spacedim> &cache,
650 const MeshType &mesh,
651 const VectorType &vector,
653 const unsigned int first_selected_component,
654 const UpdateFlags update_flags,
655 const ::EvaluationFlags::EvaluationFlags evaluation_flags,
656 const std::function<
657 value_type(const FEPointEvaluation<n_components,
658 dim,
659 spacedim,
660 typename VectorType::value_type> &,
661 const unsigned int &)> process_quadrature_point)
662 {
663 Assert(cache.is_ready(),
665 "Utilities::MPI::RemotePointEvaluation is not ready yet! "
666 "Please call Utilities::MPI::RemotePointEvaluation::reinit() "
667 "yourself or another function that does this for you."));
668
669 Assert(
670 &mesh.get_triangulation() == &cache.get_triangulation(),
672 "The provided Utilities::MPI::RemotePointEvaluation and DoFHandler "
673 "object have been set up with different Triangulation objects, "
674 "a scenario not supported!"));
675
676 // evaluate values at points if possible
677 const auto evaluation_point_results = [&]() {
678 // helper function for accessing the global vector and interpolating
679 // the results onto the points
680 const auto evaluation_function = [&](auto &values,
681 const auto &cell_data) {
682 std::vector<typename VectorType::value_type> solution_values;
683
684 std::vector<
685 std::unique_ptr<FEPointEvaluation<n_components,
686 dim,
687 spacedim,
688 typename VectorType::value_type>>>
689 evaluators;
690
691 for (unsigned int i = 0; i < cell_data.cells.size(); ++i)
692 process_cell<n_components, dim, spacedim, VectorType, value_type>(
693 i,
694 cell_data,
695 cache,
696 mesh,
697 vector,
698 update_flags,
699 evaluation_flags,
700 first_selected_component,
701 process_quadrature_point,
702 values,
703 solution_values,
704 evaluators);
705 };
706
707 std::vector<value_type> evaluation_point_results;
708 std::vector<value_type> buffer;
709
710 cache.template evaluate_and_process<value_type>(
711 evaluation_point_results, buffer, evaluation_function);
712
713 return evaluation_point_results;
714 }();
715
716 if (cache.is_map_unique())
717 {
718 // each point has exactly one result (unique map)
719 return evaluation_point_results;
720 }
721 else
722 {
723 // map is not unique (multiple or no results): postprocessing is
724 // needed
725 std::vector<value_type> unique_evaluation_point_results(
726 cache.get_point_ptrs().size() - 1);
727
728 const auto &ptr = cache.get_point_ptrs();
729
730 for (unsigned int i = 0; i < ptr.size() - 1; ++i)
731 {
732 const auto n_entries = ptr[i + 1] - ptr[i];
733 if (n_entries == 0)
734 continue;
735
736 unique_evaluation_point_results[i] =
737 reduce(flags,
738 ArrayView<const value_type>(
739 evaluation_point_results.data() + ptr[i], n_entries));
740 }
741
742 return unique_evaluation_point_results;
743 }
744 }
745 } // namespace internal
746
747 template <int n_components,
748 template <int, int>
749 class MeshType,
750 int dim,
751 int spacedim,
752 typename VectorType>
754 (concepts::is_dealii_vector_type<VectorType> &&
755 concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
756 inline std::vector<
757 typename FEPointEvaluation<n_components,
758 dim,
759 spacedim,
760 typename VectorType::value_type>::
761 value_type> point_values(const Utilities::MPI::
762 RemotePointEvaluation<dim, spacedim> &cache,
763 const MeshType<dim, spacedim> &mesh,
764 const VectorType &vector,
765 const EvaluationFlags::EvaluationFlags flags,
766 const unsigned int first_selected_component)
767 {
768 return internal::evaluate_at_points<
769 n_components,
770 dim,
771 spacedim,
772 MeshType<dim, spacedim>,
774 typename FEPointEvaluation<n_components,
775 dim,
776 spacedim,
777 typename VectorType::value_type>::value_type>(
778 cache,
779 mesh,
780 vector,
781 flags,
782 first_selected_component,
785 [](const auto &evaluator, const auto &q) {
786 return evaluator.get_value(q);
787 });
788 }
789
790
791
792 template <int n_components,
793 template <int, int>
794 class MeshType,
795 int dim,
796 int spacedim,
797 typename VectorType>
799 (concepts::is_dealii_vector_type<VectorType> &&
800 concepts::is_triangulation_or_dof_handler<MeshType<dim, spacedim>>))
801 inline std::vector<
802 typename FEPointEvaluation<n_components,
803 dim,
804 spacedim,
805 typename VectorType::value_type>::
806 gradient_type> point_gradients(const Utilities::MPI::
807 RemotePointEvaluation<dim, spacedim>
808 &cache,
809 const MeshType<dim, spacedim> &mesh,
810 const VectorType &vector,
812 flags,
813 const unsigned int
814 first_selected_component)
815 {
816 return internal::evaluate_at_points<
817 n_components,
818 dim,
819 spacedim,
820 MeshType<dim, spacedim>,
822 typename FEPointEvaluation<
823 n_components,
824 dim,
825 spacedim,
826 typename VectorType::value_type>::gradient_type>(
827 cache,
828 mesh,
829 vector,
830 flags,
831 first_selected_component,
834 [](const auto &evaluator, const unsigned &q) {
835 return evaluator.get_gradient(q);
836 });
837 }
838
839#endif
840} // namespace VectorTools
841
843
844#endif // dealii_vector_tools_boundary_h
const hp::FECollection< dim, spacedim > & get_fe_collection() const
const FiniteElement< dim, spacedim > & get_fe(const types::fe_index index=0) const
void reinit(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const ArrayView< const Point< dim > > &unit_points)
unsigned int n_dofs_per_cell() const
size_type locally_owned_size() const
Abstract base class for mapping classes.
Definition mapping.h:320
Definition point.h:113
unsigned int n_active_cells() const
const Triangulation< dim, spacedim > & get_triangulation() const
const std::vector< unsigned int > & get_point_ptrs() const
const Mapping< dim, spacedim > & get_mapping() const
virtual size_type size() const override
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:40
#define DEAL_II_CXX20_REQUIRES(condition)
Definition config.h:248
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:41
#define DEAL_II_NOT_IMPLEMENTED()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcMessage(std::string arg1)
TriaActiveIterator< CellAccessor< dim, spacedim > > active_cell_iterator
Definition tria.h:1581
typename ActiveSelector::active_cell_iterator active_cell_iterator
const bool IsBlockVector< VectorType >::value
UpdateFlags
@ update_values
Shape function values.
@ update_gradients
Shape function gradients.
MappingQ< dim, spacedim > StaticMappingQ1< dim, spacedim >::mapping
Definition mapping_q1.h:104
The namespace for the EvaluationFlags enum.
EvaluationFlags
The EvaluationFlags enum.
constexpr char T
Tpetra::Vector< Number, LO, GO, NodeType< MemorySpace > > VectorType
T reduce(const T &local_value, const MPI_Comm comm, const std::function< T(const T &, const T &)> &combiner, const unsigned int root_process=0)
std::vector< typename FEPointEvaluation< n_components, dim, spacedim, typename VectorType::value_type >::value_type > point_values(const Mapping< dim > &mapping, const MeshType< dim, spacedim > &mesh, const VectorType &vector, const std::vector< Point< spacedim > > &evaluation_points, Utilities::MPI::RemotePointEvaluation< dim, spacedim > &cache, const EvaluationFlags::EvaluationFlags flags=EvaluationFlags::avg, const unsigned int first_selected_component=0)
std::vector< typename FEPointEvaluation< n_components, dim, spacedim, typename VectorType::value_type >::gradient_type > point_gradients(const Mapping< dim > &mapping, const MeshType< dim, spacedim > &mesh, const VectorType &vector, const std::vector< Point< spacedim > > &evaluation_points, Utilities::MPI::RemotePointEvaluation< dim, spacedim > &cache, const EvaluationFlags::EvaluationFlags flags=EvaluationFlags::avg, const unsigned int first_selected_component=0)
STL namespace.