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

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/discretization/FV/discretization.hh Source File
DiFfRG
Discretization Framework for functional Renormalization Group flows
discretization.hh
Go to the documentation of this file.
1#pragma once
2
3// external libraries
4#include <deal.II/base/point.h>
5#include <deal.II/dofs/dof_handler.h>
6#include <deal.II/dofs/dof_renumbering.h>
7#include <deal.II/dofs/dof_tools.h>
8#include <deal.II/fe/fe_dgq.h>
9#include <deal.II/fe/fe_system.h>
10#include <deal.II/fe/mapping_q1.h>
11#include <deal.II/lac/affine_constraints.h>
12#include <deal.II/lac/sparse_matrix.h>
13#include <deal.II/lac/vector.h>
14
15// DiFfRG
23
24#include <iostream>
25#include <string>
26
27// std
28#include <type_traits>
29
30namespace DiFfRG
31{
32 namespace FV
33 {
34 using namespace dealii;
35
42 template <typename ModelOrComponents_, typename Mesh_, typename NumberType_ = double,
43 typename VectorType_ = LAVectorFor<Mesh_, NumberType_>,
44 typename SparseMatrixType_ = LASparseMatrixFor<Mesh_, NumberType_>>
46 {
47 public:
51 using NumberType = NumberType_;
52 using VectorType = VectorType_;
53 using SparseMatrixType = SparseMatrixType_;
54 using Mesh = Mesh_;
55 static constexpr uint dim = Mesh::dim;
56
61
63 "The VectorType is not one DiFfRG knows: see the get_type trait table in "
64 "DiFfRG/common/linear_algebra.hh.");
65
66 // The scalar type has to agree with the vector's own. PETSc fixes PetscScalar at configure
67 // time and does not template on it, so `Discretization<Model, Mesh, float>` next to a PETSc
68 // vector would otherwise silently run the model in float against a double vector.
69 static_assert(std::is_same_v<NumberType, get_type::NumberType<VectorType>>,
70 "NumberType does not match the number type of VectorType.");
71
72 // A distributed vector partitions its rows by rank ownership, which only exists once the
73 // mesh has been partitioned. Pairing one with a serial triangulation compiles cleanly and
74 // then hands every rank the same complete index set, so every rank owns every row and the
75 // assembled residual is summed n_ranks times -- a wrong answer with no error anywhere.
76 static_assert(!is_distributed || Mesh::is_parallel, "A distributed VectorType requires a partitioned mesh, i.e. "
77 "RectangularMeshParallel<dim>.");
78
79 // The converse, and the more dangerous direction. A serial vector on a partitioned mesh
80 // compiles and runs: every rank assembles only the cells it owns into a full-size vector
81 // that nothing ever sums, so the answer is silently wrong rather than absent.
82 static_assert(is_distributed || !Mesh::is_parallel,
83 "A partitioned mesh requires a distributed VectorType. Either let both follow "
84 "the build configuration, or pin the mesh serial with RectangularMeshSerial<dim>.");
85 static constexpr bool is_fv_discretization = true;
87 : mesh(mesh), config(config), log(std::move(report_port)),
88 fe(std::make_shared<FESystem<dim>>(FE_DGQ<dim>(0), Components::count_fe_functions(0))),
90 {
92 setup_dofs();
93 }
94
95 const auto &get_constraints(const uint i = 0) const
96 {
97 (void)i;
98 return constraints;
99 }
100 auto &get_constraints(const uint i = 0)
101 {
102 (void)i;
103 return constraints;
104 }
105 const auto &get_dof_handler(const uint i = 0) const
106 {
107 (void)i;
108 return dof_handler;
109 }
110 auto &get_dof_handler(const uint i = 0)
111 {
112 (void)i;
113 return dof_handler;
114 }
115 const auto &get_fe(uint i = 0) const
116 {
117 if (i != 0) throw std::runtime_error("Wrong FE index");
118 return *fe;
119 }
120 const auto &get_mapping() const { return mapping; }
121 const auto &get_triangulation() const { return mesh.get_triangulation(); }
122 auto &get_triangulation() { return mesh.get_triangulation(); }
123
130 const Point<dim> &get_support_point(const uint dof) const { return support_points[dof]; }
136 const auto &get_support_points() const { return support_points; }
137
138 const auto &get_config() const { return config; }
139 ReportPort report_port() const { return log; }
140
144 const dealii::IndexSet &get_locally_owned_dofs() const { return locally_owned_dofs; }
149 const dealii::IndexSet &get_locally_relevant_dofs() const { return locally_relevant_dofs; }
153 MPI_Comm get_communicator() const { return dof_handler.get_mpi_communicator(); }
154
155 void reinit() { setup_dofs(); }
156
157 uint get_closest_dof(const Point<dim> &p) const
158 {
159 uint dof = 0;
160 double min_dist = std::numeric_limits<double>::max();
161 for (uint i = 0; i < support_points.size(); ++i) {
162 const auto dist = p.distance(support_points[i]);
163 if (dist < min_dist) {
164 min_dist = dist;
165 dof = i;
166 }
167 }
168 return dof;
169 }
170
171 std::vector<uint> get_block_structure() const
172 {
173 std::vector<uint> block_structure{dof_handler.n_dofs()};
174 if (Components::count_variables() > 0) block_structure.push_back(Components::count_variables());
175 return block_structure;
176 }
177
178 protected:
184 {
185 const uint fe_order = config.get_uint("/discretization/fe_order", 0);
186 if (fe_order == 0) return;
187
188 const std::string message =
189 "FV: /discretization/fe_order = " + std::to_string(fe_order) +
190 " is ignored. The finite volume discretization always uses piecewise constants (fe_order = 0); "
191 "reconstruction order is set by the choice of reconstructor and limiter instead.";
192 log.warn("{}", message);
193 }
194
196 {
197 dof_handler.distribute_dofs(*fe);
198
199 log.info("FV: Number of active cells: {}", mesh.get_triangulation().n_active_cells());
200 log.info("FV: Number of degrees of freedom: {}", dof_handler.n_dofs());
201
202 constraints.clear();
203 DoFTools::make_hanging_node_constraints(dof_handler, constraints);
204 constraints.close();
205
206 locally_owned_dofs = dof_handler.locally_owned_dofs();
208
209 // NOT DoFTools::map_dofs_to_support_points(..., std::vector<Point>&): that overload is
210 // documented to *error out* on a DoFHandler built on a parallel::TriangulationBase,
211 // because its precondition is an array sized to the global dof count. See
212 // ParallelDoFs::build_support_points.
214 }
215
219
220 std::shared_ptr<FESystem<dim>> fe;
221 DoFHandler<dim> dof_handler;
222 AffineConstraints<NumberType> constraints;
223 MappingQ1<dim> mapping;
224 std::vector<Point<dim>> support_points;
225 dealii::IndexSet locally_owned_dofs;
226 dealii::IndexSet locally_relevant_dofs;
227 };
228 } // namespace FV
229} // namespace DiFfRG
A hierarchical configuration tree, readable from JSON and TOML files.
Definition config_tree.hh:32
uint get_uint(const std::string &key) const
Get the value of a key in the configuration object.
Class to manage the system on which we solve, i.e. fe spaces, grids, etc. This class is a System for ...
Definition discretization.hh:46
auto & get_constraints(const uint i=0)
Definition discretization.hh:100
const auto & get_constraints(const uint i=0) const
Definition discretization.hh:95
typename DiFfRG::internal::model_of_descriptor< ModelOrComponents_ >::type Model
The model this discretization belongs to, or void if it was built from a bare descriptor.
Definition discretization.hh:49
const auto & get_mapping() const
Definition discretization.hh:120
const Point< dim > & get_support_point(const uint dof) const
Get the support point for a given dof.
Definition discretization.hh:130
typename DiFfRG::internal::components_of< ModelOrComponents_ >::type Components
Definition discretization.hh:50
ReportPort report_port() const
Definition discretization.hh:139
static constexpr bool is_distributed
Whether the linear algebra is distributed over MPI ranks.
Definition discretization.hh:60
const auto & get_triangulation() const
Definition discretization.hh:121
ReportPort log
Definition discretization.hh:218
Mesh_ Mesh
Definition discretization.hh:54
MappingQ1< dim > mapping
Definition discretization.hh:223
const auto & get_fe(uint i=0) const
Definition discretization.hh:115
dealii::IndexSet locally_owned_dofs
Definition discretization.hh:225
auto & get_triangulation()
Definition discretization.hh:122
static constexpr uint dim
Definition discretization.hh:55
auto & get_dof_handler(const uint i=0)
Definition discretization.hh:110
Discretization(Mesh &mesh, const ConfigTree &config, ReportPort report_port={})
Definition discretization.hh:86
void setup_dofs()
Definition discretization.hh:195
std::vector< uint > get_block_structure() const
Definition discretization.hh:171
SparseMatrixType_ SparseMatrixType
Definition discretization.hh:53
DoFHandler< dim > dof_handler
Definition discretization.hh:221
const dealii::IndexSet & get_locally_owned_dofs() const
The dof rows this rank owns. Complete on a serial mesh.
Definition discretization.hh:144
MPI_Comm get_communicator() const
MPI_COMM_SELF on a serial mesh, so callers never have to branch on the build type.
Definition discretization.hh:153
const dealii::IndexSet & get_locally_relevant_dofs() const
The dof rows this rank can read. See ParallelDoFs::make_ghost_set for why this is everything at the r...
Definition discretization.hh:149
uint get_closest_dof(const Point< dim > &p) const
Definition discretization.hh:157
dealii::IndexSet locally_relevant_dofs
Definition discretization.hh:226
NumberType_ NumberType
Definition discretization.hh:51
const auto & get_dof_handler(const uint i=0) const
Definition discretization.hh:105
AffineConstraints< NumberType > constraints
Definition discretization.hh:222
const auto & get_config() const
Definition discretization.hh:138
static constexpr bool is_fv_discretization
Definition discretization.hh:85
std::vector< Point< dim > > support_points
Definition discretization.hh:224
Mesh & mesh
Definition discretization.hh:216
VectorType_ VectorType
Definition discretization.hh:52
std::shared_ptr< FESystem< dim > > fe
Definition discretization.hh:220
ConfigTree config
Definition discretization.hh:217
void reinit()
Definition discretization.hh:155
const auto & get_support_points() const
Get the support points for all dofs.
Definition discretization.hh:136
void warn_on_ignored_fe_order() const
The finite volume discretization always works on cell averages, i.e. FE_DGQ(0), and never reads /disc...
Definition discretization.hh:183
Definition run_reporter.hh:96
void warn(spdlog::format_string_t< Args... > format, Args &&...args) const
Definition run_reporter.hh:107
void info(spdlog::format_string_t< Args... > format, Args &&...args) const
Definition run_reporter.hh:103
A vector type DiFfRG's timesteppers and assemblers can work with.
Definition linear_algebra.hh:179
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
constexpr bool is_distributed_la
Whether a linear algebra type distributes its rows across MPI ranks.
Definition linear_algebra.hh:188
dealii::Vector< NumberType > LAVectorFor
Definition linear_algebra.hh:256
dealii::SparseMatrix< NumberType > LASparseMatrixFor
Definition linear_algebra.hh:257
unsigned int uint
Definition utils.hh:24
T type
Definition types.hh:25
void type
Definition types.hh:33