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

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/discretization/FEM/dg.hh Source File
DiFfRG
Discretization Framework for functional Renormalization Group flows
dg.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
24
25// std
26#include <type_traits>
27
28namespace DiFfRG
29{
30 namespace DG
31 {
32 using namespace dealii;
33
40 template <typename ModelOrComponents_, typename Mesh_, typename NumberType_ = double,
41 typename VectorType_ = LAVectorFor<Mesh_, NumberType_>,
42 typename SparseMatrixType_ = LASparseMatrixFor<Mesh_, NumberType_>>
44 {
45 public:
49 using NumberType = NumberType_;
50 using VectorType = VectorType_;
51 using SparseMatrixType = SparseMatrixType_;
52 using Mesh = Mesh_;
53 static constexpr uint dim = Mesh::dim;
54
59
61 "The VectorType is not one DiFfRG knows: see the get_type trait table in "
62 "DiFfRG/common/linear_algebra.hh.");
63
64 // The scalar type has to agree with the vector's own. PETSc fixes PetscScalar at configure
65 // time and does not template on it, so `Discretization<Model, Mesh, float>` next to a PETSc
66 // vector would otherwise silently run the model in float against a double vector.
67 static_assert(std::is_same_v<NumberType, get_type::NumberType<VectorType>>,
68 "NumberType does not match the number type of VectorType.");
69
70 // A distributed vector partitions its rows by rank ownership, which only exists once the
71 // mesh has been partitioned. Pairing one with a serial triangulation compiles cleanly and
72 // then hands every rank the same complete index set, so every rank owns every row and the
73 // assembled residual is summed n_ranks times -- a wrong answer with no error anywhere.
74 static_assert(!is_distributed || Mesh::is_parallel, "A distributed VectorType requires a partitioned mesh, i.e. "
75 "RectangularMeshParallel<dim>.");
76
77 // The converse, and the more dangerous direction. A serial vector on a partitioned mesh
78 // compiles and runs: every rank assembles only the cells it owns into a full-size vector
79 // that nothing ever sums, so the answer is silently wrong rather than absent.
80 static_assert(is_distributed || !Mesh::is_parallel,
81 "A partitioned mesh requires a distributed VectorType. Either let both follow "
82 "the build configuration, or pin the mesh serial with RectangularMeshSerial<dim>.");
83
85 : mesh(mesh), config(config), log(std::move(report_port)),
86 fe(std::make_shared<FESystem<dim>>(FE_DGQ<dim>(config.get_uint_or_warn("/discretization/fe_order", 3)),
87 Components::count_fe_functions(0))),
89 {
90 setup_dofs();
91 };
92
93 const auto &get_constraints(const uint i = 0) const
94 {
95 (void)i;
96 return constraints;
97 }
98 auto &get_constraints(const uint i = 0)
99 {
100 (void)i;
101 return constraints;
102 }
103 const auto &get_dof_handler(const uint i = 0) const
104 {
105 (void)i;
106 return dof_handler;
107 }
108 auto &get_dof_handler(const uint i = 0)
109 {
110 (void)i;
111 return dof_handler;
112 }
113 const auto &get_fe(uint i = 0) const
114 {
115 if (i != 0) throw std::runtime_error("Wrong FE index");
116 return *fe;
117 }
118 const auto &get_mapping() const { return mapping; }
119 const auto &get_triangulation() const { return mesh.get_triangulation(); }
120 auto &get_triangulation() { return mesh.get_triangulation(); }
121
128 const Point<dim> &get_support_point(const uint dof) const { return support_points[dof]; }
134 const auto &get_support_points() const { return support_points; }
135
136 const auto &get_config() const { return config; }
137 ReportPort report_port() const { return log; }
138
142 const dealii::IndexSet &get_locally_owned_dofs() const { return locally_owned_dofs; }
147 const dealii::IndexSet &get_locally_relevant_dofs() const { return locally_relevant_dofs; }
151 MPI_Comm get_communicator() const { return dof_handler.get_mpi_communicator(); }
152
153 void reinit() { setup_dofs(); }
154
155 uint get_closest_dof(const Point<dim> &p) const
156 {
157 uint dof = 0;
158 double min_dist = std::numeric_limits<double>::max();
159 for (uint i = 0; i < support_points.size(); ++i) {
160 const auto dist = p.distance(support_points[i]);
161 if (dist < min_dist) {
162 min_dist = dist;
163 dof = i;
164 }
165 }
166 return dof;
167 }
168
169 std::vector<uint> get_block_structure() const
170 {
171 std::vector<uint> block_structure{dof_handler.n_dofs()};
172 if (Components::count_variables() > 0) block_structure.push_back(Components::count_variables());
173 return block_structure;
174 }
175
176 protected:
178 {
179 dof_handler.distribute_dofs(*fe);
180
181 log.info("FEM: Number of active cells: {}", mesh.get_triangulation().n_active_cells());
182 log.info("FEM: Number of degrees of freedom: {}", dof_handler.n_dofs());
183
184 constraints.clear();
185 DoFTools::make_hanging_node_constraints(dof_handler, constraints);
186 constraints.close();
187
188 locally_owned_dofs = dof_handler.locally_owned_dofs();
190
191 // NOT DoFTools::map_dofs_to_support_points(..., std::vector<Point>&): that overload is
192 // documented to *error out* on a DoFHandler built on a parallel::TriangulationBase,
193 // because its precondition is an array sized to the global dof count. See
194 // ParallelDoFs::build_support_points.
196 }
197
201
202 std::shared_ptr<FESystem<dim>> fe;
203 DoFHandler<dim> dof_handler;
204 AffineConstraints<NumberType> constraints;
205 MappingQ1<dim> mapping;
206 std::vector<Point<dim>> support_points;
207 dealii::IndexSet locally_owned_dofs;
208 dealii::IndexSet locally_relevant_dofs;
209 };
210 } // namespace DG
211} // namespace DiFfRG
A hierarchical configuration tree, readable from JSON and TOML files.
Definition config_tree.hh:32
Class to manage the system on which we solve, i.e. fe spaces, grids, etc. This class is a System for ...
Definition dg.hh:44
std::vector< Point< dim > > support_points
Definition dg.hh:206
std::vector< uint > get_block_structure() const
Definition dg.hh:169
ReportPort report_port() const
Definition dg.hh:137
void reinit()
Definition dg.hh:153
ConfigTree config
Definition dg.hh:199
dealii::IndexSet locally_relevant_dofs
Definition dg.hh:208
DoFHandler< dim > dof_handler
Definition dg.hh:203
void setup_dofs()
Definition dg.hh:177
Mesh & mesh
Definition dg.hh:198
Mesh_ Mesh
Definition dg.hh:52
const auto & get_support_points() const
Get the support points for all dofs.
Definition dg.hh:134
const Point< dim > & get_support_point(const uint dof) const
Get the support point for a given dof.
Definition dg.hh:128
dealii::IndexSet locally_owned_dofs
Definition dg.hh:207
const auto & get_constraints(const uint i=0) const
Definition dg.hh:93
typename DiFfRG::internal::components_of< ModelOrComponents_ >::type Components
Definition dg.hh:48
SparseMatrixType_ SparseMatrixType
Definition dg.hh:51
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 dg.hh:147
MappingQ1< dim > mapping
Definition dg.hh:205
auto & get_dof_handler(const uint i=0)
Definition dg.hh:108
VectorType_ VectorType
Definition dg.hh:50
auto & get_constraints(const uint i=0)
Definition dg.hh:98
ReportPort log
Definition dg.hh:200
AffineConstraints< NumberType > constraints
Definition dg.hh:204
const auto & get_dof_handler(const uint i=0) const
Definition dg.hh:103
const auto & get_fe(uint i=0) const
Definition dg.hh:113
const auto & get_config() const
Definition dg.hh:136
Discretization(Mesh &mesh, const ConfigTree &config, ReportPort report_port={})
Definition dg.hh:84
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 dg.hh:47
const auto & get_mapping() const
Definition dg.hh:118
NumberType_ NumberType
Definition dg.hh:49
static constexpr bool is_distributed
Whether the linear algebra is distributed over MPI ranks.
Definition dg.hh:58
const auto & get_triangulation() const
Definition dg.hh:119
auto & get_triangulation()
Definition dg.hh:120
MPI_Comm get_communicator() const
MPI_COMM_SELF on a serial mesh, so callers never have to branch on the build type.
Definition dg.hh:151
const dealii::IndexSet & get_locally_owned_dofs() const
The dof rows this rank owns. Complete on a serial mesh.
Definition dg.hh:142
uint get_closest_dof(const Point< dim > &p) const
Definition dg.hh:155
static constexpr uint dim
Definition dg.hh:53
std::shared_ptr< FESystem< dim > > fe
Definition dg.hh:202
Definition run_reporter.hh:96
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