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

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/discretization/common/solution_sample.hh Source File
DiFfRG
Discretization Framework for functional Renormalization Group flows
solution_sample.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/base/quadrature_lib.h>
6#include <deal.II/base/tensor.h>
7#include <deal.II/dofs/dof_handler.h>
8#include <deal.II/fe/fe_values.h>
9#include <deal.II/lac/vector.h>
10
11// DiFfRG
13
14// standard library
15#include <algorithm>
16#include <concepts>
17#include <vector>
18
19namespace DiFfRG
20{
22 template <int dim> dealii::Point<dim> unit_cell_centre()
23 {
24 dealii::Point<dim> centre;
25 for (uint d = 0; d < dim; ++d)
26 centre[d] = 0.5;
27 return centre;
28 }
29
31 template <int dim, typename NumberType> struct SolutionSampleEntry {
33 dealii::Point<dim> point;
35 double cell_width;
37 std::vector<NumberType> values;
39 std::vector<dealii::Tensor<1, dim, NumberType>> gradients;
40 };
41
60 template <int dim, typename NumberType> class SolutionSample
61 {
62 public:
64
65 SolutionSample() = default;
66 SolutionSample(std::vector<Entry> entries, const uint n_components)
68 {
69 std::sort(this->entries.begin(), this->entries.end(), [](const Entry &a, const Entry &b) {
70 for (uint d = 0; d < dim; ++d)
71 if (a.point[d] != b.point[d]) return a.point[d] < b.point[d];
72 return false;
73 });
74 }
75
76 size_t size() const { return entries.size(); }
77 bool empty() const { return entries.empty(); }
78 uint n_components() const { return m_n_components; }
79
80 const Entry &operator[](const size_t i) const { return entries[i]; }
81 auto begin() const { return entries.begin(); }
82 auto end() const { return entries.end(); }
83
95 {
96 if constexpr (dim != 1) return;
97 if (entries.size() < 2) return;
98 for (size_t i = 0; i < entries.size(); ++i) {
99 const size_t lo = (i == 0) ? 0 : i - 1;
100 const size_t hi = std::min(i + 1, entries.size() - 1);
101 const double dx = entries[hi].point[0] - entries[lo].point[0];
102 for (uint c = 0; c < m_n_components; ++c)
103 entries[i].gradients[c][0] = dx != 0. ? (entries[hi].values[c] - entries[lo].values[c]) / dx : NumberType(0.);
104 }
105 }
106
107 private:
108 std::vector<Entry> entries;
110 };
111
136 template <typename Model, int dim, typename NumberType>
137 concept HasExtractorPoint = requires(const Model &model, const dealii::Point<dim> &EoM,
138 const SolutionSample<dim, NumberType> &sample) {
139 { model.template extractor_point<dim, NumberType>(EoM, sample) } -> std::convertible_to<dealii::Point<dim>>;
140 };
141
153 template <int dim, typename NumberType, typename FillFUN>
154 SolutionSample<dim, NumberType> make_solution_sample(const dealii::DoFHandler<dim> &dof_handler,
155 const dealii::Mapping<dim> &mapping, const uint n_components,
156 const FillFUN &fill)
157 {
158 std::vector<SolutionSampleEntry<dim, NumberType>> entries;
159 entries.reserve(dof_handler.get_triangulation().n_active_cells());
160
161 for (const auto &cell : dof_handler.active_cell_iterators()) {
163 entry.point = mapping.transform_unit_to_real_cell(cell, unit_cell_centre<dim>());
164 entry.cell_width = internal::cell_width(cell);
165 entry.values.resize(n_components);
166 entry.gradients.resize(n_components);
167 fill(cell, entry.point, entry.values, entry.gradients);
168 entries.push_back(std::move(entry));
169 }
170
171 return SolutionSample<dim, NumberType>(std::move(entries), n_components);
172 }
173
181 template <int dim, typename VectorType>
182 SolutionSample<dim, typename VectorType::value_type>
183 make_solution_sample(const VectorType &solution, const dealii::DoFHandler<dim> &dof_handler,
184 const dealii::Mapping<dim> &mapping)
185 {
186 using NumberType = typename VectorType::value_type;
187 const uint n_components = dof_handler.get_fe().n_components();
188
189 const dealii::QMidpoint<dim> midpoint;
190 dealii::FEValues<dim> fe_v(mapping, dof_handler.get_fe(), midpoint,
191 dealii::update_values | dealii::update_gradients);
192 std::vector<dealii::Vector<NumberType>> cell_values(1, dealii::Vector<NumberType>(n_components));
193 std::vector<std::vector<dealii::Tensor<1, dim, NumberType>>> cell_gradients(
194 1, std::vector<dealii::Tensor<1, dim, NumberType>>(n_components));
195
197 dof_handler, mapping, n_components,
198 [&](const auto &cell, const dealii::Point<dim> &, std::vector<NumberType> &values,
199 std::vector<dealii::Tensor<1, dim, NumberType>> &gradients) {
200 fe_v.reinit(cell);
201 fe_v.get_function_values(solution, cell_values);
202 fe_v.get_function_gradients(solution, cell_gradients);
203 for (uint c = 0; c < values.size(); ++c) {
204 values[c] = cell_values[0][c];
205 gradients[c] = cell_gradients[0][c];
206 }
207 });
208 }
209} // namespace DiFfRG
A read-only snapshot of the discrete solution, one sample per active cell.
Definition solution_sample.hh:61
auto end() const
Definition solution_sample.hh:82
const Entry & operator[](const size_t i) const
Definition solution_sample.hh:80
uint n_components() const
Definition solution_sample.hh:78
SolutionSample(std::vector< Entry > entries, const uint n_components)
Definition solution_sample.hh:66
auto begin() const
Definition solution_sample.hh:81
bool empty() const
Definition solution_sample.hh:77
void compute_central_difference_gradients()
Fill the gradients by central differences between neighbouring samples.
Definition solution_sample.hh:94
size_t size() const
Definition solution_sample.hh:76
uint m_n_components
Definition solution_sample.hh:109
std::vector< Entry > entries
Definition solution_sample.hh:108
Whether Model chooses its own point at which the extractors are evaluated.
Definition solution_sample.hh:137
double cell_width(const CellIterator &cell)
The smallest face-normal width over all faces of cell.
Definition cell_geometry.hh:42
Definition complex_math.hh:10
dealii::Point< dim > unit_cell_centre()
The centre of the reference cell.
Definition solution_sample.hh:22
unsigned int uint
Definition utils.hh:24
SolutionSample< dim, NumberType > make_solution_sample(const dealii::DoFHandler< dim > &dof_handler, const dealii::Mapping< dim > &mapping, const uint n_components, const FillFUN &fill)
Build a SolutionSample, taking values and gradients from a callback.
Definition solution_sample.hh:154
One cell's worth of a SolutionSample.
Definition solution_sample.hh:31
std::vector< dealii::Tensor< 1, dim, NumberType > > gradients
Solution gradients at point, one per component.
Definition solution_sample.hh:39
double cell_width
Smallest face-normal width of the cell, i.e. the local grid spacing.
Definition solution_sample.hh:35
std::vector< NumberType > values
Solution values at point, one per component.
Definition solution_sample.hh:37
dealii::Point< dim > point
Cell centre.
Definition solution_sample.hh:33