/home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/model/component_descriptor.hh Source File#

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/model/component_descriptor.hh Source File
DiFfRG
component_descriptor.hh
Go to the documentation of this file.
1#pragma once
2
3// standard library
4#include <array>
5#include <utility>
6
7// external libraries
8#include <deal.II/dofs/dof_tools.h>
9
10// DiFfRG
12
13namespace DiFfRG
14{
21 template <FixedString _str, size_t... _val> struct FunctionND {
22 static constexpr FixedString name = _str;
23 static constexpr size_t size = (_val * ...);
24 static constexpr size_t dim = sizeof...(_val);
25 static constexpr std::array<size_t, dim> nd_sizes{{_val...}};
26 };
27
28 /*
29 * @brief A class to describe a scalar variable.
30 *
31 * @tparam _str The name of the variable.
32 */
33 template <FixedString _str> struct Scalar {
34 /*
35 You're probably wondering why this is not a specialization of FunctionND.
36 Well, depending on your compiler, this may end up in a wierd bug, where it messes up the internals of the array in
37 FixedString. I was not able to fully debug this, and therefore we circumvent the problem by very explicitly defining
38 the Scalar class.
39 */
40 static constexpr FixedString name = _str;
41 static constexpr size_t size = 1;
42 static constexpr size_t dim = 1;
43 static constexpr std::array<size_t, dim> nd_sizes{{1}};
44 };
45
46 template <typename... _descriptors> struct SubDescriptor {
47 // tuple of all FixedString names
48 static constexpr auto names_tuple = std::tie(_descriptors::name...);
49
50 static constexpr std::array<const char *, sizeof...(_descriptors)> names{{_descriptors::name...}};
51 static constexpr std::array<size_t, sizeof...(_descriptors)> sizes{{_descriptors::size...}};
52 using descriptor_tuple = std::tuple<_descriptors...>;
53
54 static constexpr size_t total_size = (0 + ... + _descriptors::size);
55
56 // If two names are the same, the program should not compile
57 static_assert(
58 []<size_t... I>(std::index_sequence<I...>) {
59 if constexpr (sizeof...(_descriptors) > 1)
60 for (size_t i : {I...})
61 for (size_t j : {I...})
62 if (i != j && strings_equal(names[i], names[j])) return false;
63 return true;
64 }(std::make_index_sequence<sizeof...(_descriptors)>{}),
65 "Names of a SubDescriptor must be unique!");
66
67 template <unsigned N> consteval size_t get(FixedString<N> name) const
68 {
69 size_t running_sum = 0;
70 for (size_t i = 0; i < names.size(); ++i) {
71 // if (0 == std::strcmp(names[i], name)) return running_sum;
72 if(strings_equal(names[i], name)) return running_sum;
73 running_sum += sizes[i];
74 }
75 // produce a compile-time error if the name is not found in the list
76 throw std::invalid_argument(
77 "SubDescriptor::get: Name \"" + std::string(name) +
78 "\" not found. Available names are: " + ((std::string(_descriptors::name) + "; ") + ...));
79 }
80
81 template <unsigned N> consteval size_t operator[](FixedString<N> name) const { return get(name); }
82 template <unsigned N> consteval size_t operator()(FixedString<N> name) const { return get(name); }
83
84 template <unsigned N> consteval size_t operator[](char const(&arr)[N]) const { return get( FixedString<N-1>(arr) ); }
85 template <unsigned N> consteval size_t operator()(char const(&arr)[N]) const { return get( FixedString<N-1>(arr) ); }
86
87 consteval char const *name(size_t index) const { return names[index]; }
88
89 consteval std::array<const char *, sizeof...(_descriptors)> get_names() const { return names; }
90 static std::vector<std::string> get_names_vector() { return {names.begin(), names.end()}; }
91
92 template<unsigned N>
93 consteval size_t size(char const(&arr)[N]) const
94 {
95 for (size_t i = 0; i < names.size(); ++i)
96 if(strings_equal(names[i], arr)) return sizes[i];
97 throw std::invalid_argument(
98 "SubDescriptor::size: Name \"" + std::string(arr) +
99 "\" not found. Available names are: " + ((std::string(_descriptors::name) + "; ") + ...));
100 }
101 };
102
103 template <typename... descriptors> using FEFunctionDescriptor = SubDescriptor<descriptors...>;
104 template <typename... descriptors> using VariableDescriptor = SubDescriptor<descriptors...>;
105 template <typename... descriptors> using ExtractorDescriptor = SubDescriptor<descriptors...>;
106
114 template <typename _FEFunctionDescriptor, typename _VariableDescriptor = VariableDescriptor<>,
115 typename _ExtractorDescriptor = ExtractorDescriptor<>, typename... LDGDescriptors>
117 {
118 using CouplingList = std::vector<std::array<uint, 2>>;
119
120 public:
121 using FEFunction_Descriptor = _FEFunctionDescriptor;
122 using Variable_Descriptor = _VariableDescriptor;
123 using Extractor_Descriptor = _ExtractorDescriptor;
124
125 private:
126 static constexpr uint n_fe_subsystems = sizeof...(LDGDescriptors) + 1;
127 static constexpr std::array<uint, n_fe_subsystems> n_components{
128 {FEFunction_Descriptor::total_size, LDGDescriptors::total_size...}};
129 static constexpr uint n_variables = Variable_Descriptor::total_size;
130 static constexpr uint n_extractors = Extractor_Descriptor::total_size;
131
132 public:
134 {
135 for (auto &dep : j_const)
136 for (auto &indep : dep)
137 indep = false;
138 }
139
148 void add_dependency(uint dependent_subsystem, uint dependent, uint independent_subsystem, uint independent)
149 {
150 if (dependent_subsystem >= n_fe_subsystems || independent_subsystem >= n_fe_subsystems)
151 throw std::runtime_error("The subsystems described by 'add_dependency' do not exist.");
152
153 if (dependent_subsystem != independent_subsystem + 1)
154 throw std::runtime_error(
155 "The model should only specify dependencies between fe subsystems at neighboring levels.");
156
157 couplings[dependent_subsystem][independent_subsystem].push_back({{dependent, independent}});
158
159 if (independent_subsystem > 0) {
160 for (const auto &dependency : couplings[independent_subsystem][independent_subsystem - 1])
161 if (dependency[0] == independent)
162 couplings[dependent_subsystem][independent_subsystem - 1].push_back({{dependent, dependency[1]}});
163 }
164 }
165
166 void set_jacobian_constant(uint dependent_subsystem, uint independent_subsystem)
167 {
168 if (dependent_subsystem >= n_fe_subsystems || independent_subsystem >= n_fe_subsystems)
169 throw std::runtime_error("The subsystems described by 'add_dependency' do not exist.");
170
171 if (dependent_subsystem != independent_subsystem + 1)
172 throw std::runtime_error(
173 "The model should only specify dependencies between fe subsystems at neighboring levels.");
174 j_const[dependent_subsystem][independent_subsystem] = true;
175
176 if (independent_subsystem > 0)
177 if (j_const[independent_subsystem][independent_subsystem - 1])
178 j_const[dependent_subsystem][independent_subsystem - 1] = true;
179 }
180
181 const CouplingList &ldg_couplings(uint dependent_subsystem, uint independent_subsystem) const
182 {
183 return couplings[dependent_subsystem][independent_subsystem];
184 }
185 bool jacobians_constant(uint dependent_subsystem, uint independent_subsystem) const
186 {
187 return j_const[dependent_subsystem][independent_subsystem];
188 }
189
190 static constexpr uint count_fe_functions(uint subsystem = 0) { return n_components[subsystem]; }
191 static constexpr uint count_variables() { return n_variables; }
192 static constexpr uint count_extractors() { return n_extractors; }
193 static constexpr uint count_fe_subsystems() { return n_fe_subsystems; }
194
195 template <typename DoFH> static std::vector<uint> get_component_block_structure(const DoFH &dofh)
196 {
197 std::vector<uint> dofs_per_component = dealii::DoFTools::count_dofs_per_fe_component(dofh);
198 return dofs_per_component;
199 }
200
201 private:
202 template <typename T> using SubsystemMatrix = std::array<std::array<T, n_fe_subsystems>, n_fe_subsystems>;
203
206 };
207} // namespace DiFfRG
A class to describe how many FE functions, additional variables and extractors are used in a model.
Definition component_descriptor.hh:117
ComponentDescriptor()
Definition component_descriptor.hh:133
_VariableDescriptor Variable_Descriptor
Definition component_descriptor.hh:122
void set_jacobian_constant(uint dependent_subsystem, uint independent_subsystem)
Definition component_descriptor.hh:166
static constexpr uint count_variables()
Definition component_descriptor.hh:191
SubsystemMatrix< bool > j_const
Definition component_descriptor.hh:205
static constexpr std::array< uint, n_fe_subsystems > n_components
Definition component_descriptor.hh:127
static constexpr uint count_fe_functions(uint subsystem=0)
Definition component_descriptor.hh:190
bool jacobians_constant(uint dependent_subsystem, uint independent_subsystem) const
Definition component_descriptor.hh:185
static constexpr uint count_extractors()
Definition component_descriptor.hh:192
const CouplingList & ldg_couplings(uint dependent_subsystem, uint independent_subsystem) const
Definition component_descriptor.hh:181
void add_dependency(uint dependent_subsystem, uint dependent, uint independent_subsystem, uint independent)
Add a dependency between two FE subsystems, i.e. for LDG constructions.
Definition component_descriptor.hh:148
static constexpr uint n_extractors
Definition component_descriptor.hh:130
_ExtractorDescriptor Extractor_Descriptor
Definition component_descriptor.hh:123
static constexpr uint n_fe_subsystems
Definition component_descriptor.hh:126
std::array< std::array< T, n_fe_subsystems >, n_fe_subsystems > SubsystemMatrix
Definition component_descriptor.hh:202
static constexpr uint n_variables
Definition component_descriptor.hh:129
static std::vector< uint > get_component_block_structure(const DoFH &dofh)
Definition component_descriptor.hh:195
std::vector< std::array< uint, 2 > > CouplingList
Definition component_descriptor.hh:118
_FEFunctionDescriptor FEFunction_Descriptor
Definition component_descriptor.hh:121
static constexpr uint count_fe_subsystems()
Definition component_descriptor.hh:193
SubsystemMatrix< CouplingList > couplings
Definition component_descriptor.hh:204
Definition complex_math.hh:10
consteval bool strings_equal(FixedString< N1 > s1, FixedString< N2 > s2)
Definition fixed_string.hh:49
unsigned int uint
Definition utils.hh:24
A fixed size compile-time string.
Definition fixed_string.hh:12
A class to describe a function with a compile-time name and a fixed number of dimensions.
Definition component_descriptor.hh:21
static constexpr FixedString name
Definition component_descriptor.hh:22
static constexpr size_t size
Definition component_descriptor.hh:23
static constexpr size_t dim
Definition component_descriptor.hh:24
static constexpr std::array< size_t, dim > nd_sizes
Definition component_descriptor.hh:25
Definition component_descriptor.hh:33
static constexpr std::array< size_t, dim > nd_sizes
Definition component_descriptor.hh:43
static constexpr size_t dim
Definition component_descriptor.hh:42
static constexpr size_t size
Definition component_descriptor.hh:41
static constexpr FixedString name
Definition component_descriptor.hh:40
Definition component_descriptor.hh:46
consteval size_t operator()(char const(&arr)[N]) const
Definition component_descriptor.hh:85
static std::vector< std::string > get_names_vector()
Definition component_descriptor.hh:90
consteval size_t operator()(FixedString< N > name) const
Definition component_descriptor.hh:82
static constexpr std::array< const char *, sizeof...(_descriptors)> names
Definition component_descriptor.hh:50
consteval char const * name(size_t index) const
Definition component_descriptor.hh:87
consteval std::array< const char *, sizeof...(_descriptors)> get_names() const
Definition component_descriptor.hh:89
static constexpr size_t total_size
Definition component_descriptor.hh:54
consteval size_t operator[](FixedString< N > name) const
Definition component_descriptor.hh:81
static constexpr auto names_tuple
Definition component_descriptor.hh:48
consteval size_t operator[](char const(&arr)[N]) const
Definition component_descriptor.hh:84
static constexpr std::array< size_t, sizeof...(_descriptors)> sizes
Definition component_descriptor.hh:51
consteval size_t get(FixedString< N > name) const
Definition component_descriptor.hh:67
consteval size_t size(char const(&arr)[N]) const
Definition component_descriptor.hh:93
std::tuple< _descriptors... > descriptor_tuple
Definition component_descriptor.hh:52