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

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