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

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/discretization/FEM/ldg.hh Source File
DiFfRG
Discretization Framework for functional Renormalization Group flows
ldg.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
13// DiFfRG
14#include <DiFfRG/common/mpi.hh>
21
22namespace DiFfRG
23{
24 namespace LDG
25 {
26 using namespace dealii;
27
34 template <typename ModelOrComponents_, typename Mesh_, typename NumberType_ = double> class Discretization
35 {
36 public:
40 using NumberType = NumberType_;
41 using VectorType = Vector<NumberType>;
42 using SparseMatrixType = BlockSparseMatrix<NumberType>;
43 using Mesh = Mesh_;
44 static constexpr uint dim = Mesh::dim;
45
46 // LDG is deliberately excluded from the distributed policy, so it fixes serial linear
47 // algebra above rather than taking VectorType_/SparseMatrixType_ parameters. Three things
48 // block it, all structural: DoFRenumbering::component_wise assumes globally contiguous
49 // per-component blocks, which a parallel DoFHandler destroys (it renumbers per rank), and
50 // the BlockSparsityPattern sizing depends on that; the LDG jacobian does sparse
51 // matrix-matrix products, for which dealii::SparseMatrix::mmult has no PETSc analogue in
52 // the same API; and the component mass matrix is factorised with SparseDirectUMFPACK.
53 //
54 // Serial vectors on a *partitioned* mesh would still compile, and would only fail later
55 // and obscurely -- setup_dofs calls the std::vector overload of map_dofs_to_support_points,
56 // which deal.II documents as unsuitable for a parallel::TriangulationBase. Reject the
57 // combination here instead, where the message can name the cause.
58 static_assert(!Mesh::is_parallel,
59 "LDG does not support a partitioned mesh. Use RectangularMeshSerial<dim>, or pick "
60 "CG/DG/dDG/KT for a distributed run. Note that a plain RectangularMesh<dim> is "
61 "partitioned in an MPI build, so LDG has to name the serial mesh explicitly.");
62
64 : mesh(mesh), config(config), log(std::move(report_port))
65 {
66 static_assert(Components::count_fe_subsystems() > 1,
67 "LDG must have a defined submodel of the Model with index 1.");
68 for (uint i = 0; i < Components::count_fe_subsystems(); ++i) {
69 fe.emplace_back(std::make_shared<FESystem<dim>>(
70 FE_DGQ<dim>(config.get_uint_or_warn("/discretization/fe_order", 3)), Components::count_fe_functions(i)));
71 dof_handler.emplace_back(std::make_shared<DoFHandler<dim>>(mesh.get_triangulation()));
72 constraints.emplace_back();
73 }
74 setup_dofs();
75 };
76
77 const auto &get_constraints(const uint i = 0) const { return constraints[i]; }
78 auto &get_constraints(const uint i = 0)
79 {
80 (void)i;
81 return constraints[i];
82 }
83 const auto &get_dof_handler(const uint i = 0) const { return *(dof_handler[i]); }
84 auto &get_dof_handler(const uint i = 0) { return *(dof_handler[i]); }
86 {
87 std::vector<const DoFHandler<dim> *> ret;
88 for (uint i = 0; i < Components::count_fe_subsystems(); ++i)
89 ret.push_back(&(get_dof_handler(i)));
90 return ret;
91 }
92 const auto &get_fe(uint i = 0) const { return *(fe[i]); }
93 const auto &get_mapping() const { return mapping; }
94 const auto &get_triangulation() const { return mesh.get_triangulation(); }
95 auto &get_triangulation() { return mesh.get_triangulation(); }
96
103 const Point<dim> &get_support_point(const uint dof) const { return support_points[dof]; }
109 const auto &get_support_points() const { return support_points; }
110
111 const auto &get_config() const { return config; }
112 ReportPort report_port() const { return log; }
113
114 // LDG is deliberately excluded from the distributed policy: DoFRenumbering::component_wise
115 // assumes globally contiguous per-component blocks, which a parallel DoFHandler destroys, and
116 // the assembler does sparse matrix-matrix products and a UMFPACK factorisation with no PETSc
117 // analogue. These three accessors exist only because LDG shares FE::FlowingVariables with
118 // CG/DG, which now asks every discretization for its layout. On the serial triangulation LDG
119 // is restricted to, they are exactly the trivial answers.
120 const dealii::IndexSet &get_locally_owned_dofs() const { return locally_owned_dofs; }
121 const dealii::IndexSet &get_locally_relevant_dofs() const { return locally_relevant_dofs; }
122 MPI_Comm get_communicator() const { return dof_handler[0]->get_mpi_communicator(); }
123
124 void reinit() { setup_dofs(); }
125
126 uint get_closest_dof(const Point<dim> &p) const
127 {
128 uint dof = 0;
129 double min_dist = std::numeric_limits<double>::max();
130 for (uint i = 0; i < support_points.size(); ++i) {
131 const auto dist = p.distance(support_points[i]);
132 if (dist < min_dist) {
133 min_dist = dist;
134 dof = i;
135 }
136 }
137 return dof;
138 }
139
140 std::vector<uint> get_block_structure() const
141 {
142 std::vector<uint> block_structure{dof_handler[0]->n_dofs()};
143 if (Components::count_variables() > 0) block_structure.push_back(Components::count_variables());
144 return block_structure;
145 }
146
147 protected:
149 {
150 log.info("FEM: Number of active cells: {}", mesh.get_triangulation().n_active_cells());
151
152 for (uint i = 0; i < Components::count_fe_subsystems(); ++i) {
153 dof_handler[i]->distribute_dofs(*(fe[i]));
154 DoFRenumbering::component_wise(*(dof_handler[i]));
155 constraints[i].clear();
156 DoFTools::make_hanging_node_constraints(*(dof_handler[i]), constraints[i]);
157 constraints[i].close();
158
159 if (i == 0) log.info("FEM: Number of degrees of freedom: {}", dof_handler[0]->n_dofs());
160 }
161
162 locally_owned_dofs = dof_handler[0]->locally_owned_dofs();
163 locally_relevant_dofs = dealii::complete_index_set(dof_handler[0]->n_dofs());
164
165 support_points.resize(dof_handler[0]->n_dofs());
166 DoFTools::map_dofs_to_support_points(mapping, *dof_handler[0], support_points);
167 }
168
172
173 std::vector<std::shared_ptr<FESystem<dim>>> fe;
174 std::vector<std::shared_ptr<DoFHandler<dim>>> dof_handler;
175 std::vector<AffineConstraints<NumberType>> constraints;
176 MappingQ1<dim> mapping;
177 std::vector<Point<dim>> support_points;
178 dealii::IndexSet locally_owned_dofs;
179 dealii::IndexSet locally_relevant_dofs;
180 };
181 } // namespace LDG
182} // namespace DiFfRG
A hierarchical configuration tree, readable from JSON and TOML files.
Definition config_tree.hh:32
uint get_uint_or_warn(const std::string &key, const uint def) const
Class to manage the system on which we solve, i.e. fe spaces, grids, etc. This class is a System for ...
Definition ldg.hh:35
MPI_Comm get_communicator() const
Definition ldg.hh:122
Discretization(Mesh &mesh, const ConfigTree &config, ReportPort report_port={})
Definition ldg.hh:63
static constexpr uint dim
Definition ldg.hh:44
std::vector< AffineConstraints< NumberType > > constraints
Definition ldg.hh:175
dealii::IndexSet locally_owned_dofs
Definition ldg.hh:178
const auto & get_support_points() const
Get the support points for all dofs.
Definition ldg.hh:109
Mesh & mesh
Definition ldg.hh:169
const dealii::IndexSet & get_locally_relevant_dofs() const
Definition ldg.hh:121
auto & get_dof_handler(const uint i=0)
Definition ldg.hh:84
Mesh_ Mesh
Definition ldg.hh:43
Vector< NumberType > VectorType
Definition ldg.hh:41
auto & get_constraints(const uint i=0)
Definition ldg.hh:78
typename DiFfRG::internal::components_of< ModelOrComponents_ >::type Components
Definition ldg.hh:39
const auto & get_fe(uint i=0) const
Definition ldg.hh:92
std::vector< std::shared_ptr< FESystem< dim > > > fe
Definition ldg.hh:173
const Point< dim > & get_support_point(const uint dof) const
Get the support point for a given dof.
Definition ldg.hh:103
auto get_dof_handler_list() const
Definition ldg.hh:85
BlockSparseMatrix< NumberType > SparseMatrixType
Definition ldg.hh:42
ReportPort report_port() const
Definition ldg.hh:112
MappingQ1< dim > mapping
Definition ldg.hh:176
const dealii::IndexSet & get_locally_owned_dofs() const
Definition ldg.hh:120
const auto & get_triangulation() const
Definition ldg.hh:94
const auto & get_dof_handler(const uint i=0) const
Definition ldg.hh:83
void setup_dofs()
Definition ldg.hh:148
std::vector< Point< dim > > support_points
Definition ldg.hh:177
const auto & get_constraints(const uint i=0) const
Definition ldg.hh:77
const auto & get_mapping() const
Definition ldg.hh:93
NumberType_ NumberType
Definition ldg.hh:40
dealii::IndexSet locally_relevant_dofs
Definition ldg.hh:179
void reinit()
Definition ldg.hh:124
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 ldg.hh:38
auto & get_triangulation()
Definition ldg.hh:95
std::vector< uint > get_block_structure() const
Definition ldg.hh:140
uint get_closest_dof(const Point< dim > &p) const
Definition ldg.hh:126
const auto & get_config() const
Definition ldg.hh:111
ConfigTree config
Definition ldg.hh:170
std::vector< std::shared_ptr< DoFHandler< dim > > > dof_handler
Definition ldg.hh:174
ReportPort log
Definition ldg.hh:171
Definition run_reporter.hh:96
void info(spdlog::format_string_t< Args... > format, Args &&...args) const
Definition run_reporter.hh:103
Definition complex_math.hh:10
unsigned int uint
Definition utils.hh:24
T type
Definition types.hh:25
void type
Definition types.hh:33