/home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/discretization/common/parallel_dofs.hh Source File#

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/discretization/common/parallel_dofs.hh Source File
DiFfRG
Discretization Framework for functional Renormalization Group flows
parallel_dofs.hh
Go to the documentation of this file.
1#pragma once
2
3// external libraries
4#include <deal.II/base/index_set.h>
5#include <deal.II/base/point.h>
6#include <deal.II/dofs/dof_handler.h>
7#include <deal.II/dofs/dof_tools.h>
8#include <deal.II/distributed/tria_base.h>
9#include <deal.II/fe/mapping.h>
10
11// DiFfRG
12#include <DiFfRG/common/mpi.hh>
13
14// std
15#include <limits>
16#include <stdexcept>
17#include <string>
18#include <vector>
19
20namespace DiFfRG
21{
28 namespace ParallelDoFs
29 {
45 template <int dim, int spacedim>
46 dealii::IndexSet make_ghost_set(const dealii::DoFHandler<dim, spacedim> &dof_handler)
47 {
48 return dealii::complete_index_set(dof_handler.n_dofs());
49 }
50
68 template <int dim, int spacedim>
69 void build_support_points(const dealii::Mapping<dim, spacedim> &mapping,
70 const dealii::DoFHandler<dim, spacedim> &dof_handler,
71 std::vector<dealii::Point<spacedim>> &support_points)
72 {
73 const auto n_dofs = dof_handler.n_dofs();
74 support_points.assign(n_dofs, dealii::Point<spacedim>());
75
76 const bool is_parallel =
77 (dynamic_cast<const dealii::parallel::TriangulationBase<dim, spacedim> *>(
78 &dof_handler.get_triangulation()) != nullptr);
79
80 if (!is_parallel) {
81 dealii::DoFTools::map_dofs_to_support_points(mapping, dof_handler, support_points);
82 return;
83 }
84
85 // Flat [n_dofs * spacedim] buffer so the reduction is a single collective. lowest() marks
86 // "this rank knows nothing about this dof"; max() then picks the real value from whichever
87 // rank does.
88 constexpr double unset = std::numeric_limits<double>::lowest();
89 std::vector<double> flat(static_cast<std::size_t>(n_dofs) * spacedim, unset);
90
91 const auto local_points = dealii::DoFTools::map_dofs_to_support_points(mapping, dof_handler);
92 for (const auto &[dof, point] : local_points)
93 for (uint d = 0; d < spacedim; ++d)
94 flat[static_cast<std::size_t>(dof) * spacedim + d] = point[d];
95
96 MPI::max_reduce(dof_handler.get_mpi_communicator(), flat.data(), static_cast<int>(flat.size()));
97
98 for (dealii::types::global_dof_index i = 0; i < n_dofs; ++i)
99 for (uint d = 0; d < spacedim; ++d) {
100 const double value = flat[static_cast<std::size_t>(i) * spacedim + d];
101 if (value == unset)
102 throw std::runtime_error("ParallelDoFs::build_support_points: dof " + std::to_string(i) +
103 " was not locally relevant on any rank. The ghost set is "
104 "narrower than the dof distribution, which would silently "
105 "corrupt every support-point lookup.");
106 support_points[i][d] = value;
107 }
108 }
109 } // namespace ParallelDoFs
110} // namespace DiFfRG
void max_reduce(MPI_Comm comm, int *data, int size)
dealii::IndexSet make_ghost_set(const dealii::DoFHandler< dim, spacedim > &dof_handler)
The ghost (locally relevant) set used by the replicated-mesh policy: everything.
Definition parallel_dofs.hh:46
void build_support_points(const dealii::Mapping< dim, spacedim > &mapping, const dealii::DoFHandler< dim, spacedim > &dof_handler, std::vector< dealii::Point< spacedim > > &support_points)
Fill a dense, mesh-wide support point array on every rank.
Definition parallel_dofs.hh:69
Definition complex_math.hh:10
unsigned int uint
Definition utils.hh:24