DiFfRG
Loading...
Searching...
No Matches
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{
15 template <FixedString _str, size_t... _val> struct NDBlock {
16 static constexpr FixedString name = _str;
17 static constexpr size_t size = (_val * ...);
18 static constexpr size_t dim = sizeof...(_val);
19 static constexpr std::array<size_t, dim> nd_sizes{{_val...}};
20 };
21
22 template <FixedString _str> using Scalar = NDBlock<_str, 1>;
23 template <FixedString _str, size_t... _val> using FunctionND = NDBlock<_str, _val...>;
24
25 template <typename... _descriptors> struct SubDescriptor {
26 static constexpr std::array<const char *, sizeof...(_descriptors)> names{{_descriptors::name...}};
27 static constexpr std::array<size_t, sizeof...(_descriptors)> sizes{{_descriptors::size...}};
28 using descriptor_tuple = std::tuple<_descriptors...>;
29
30 static constexpr size_t total_size = (0 + ... + _descriptors::size);
31
32 // If two names are the same, the program should not compile
33 static_assert(
34 []<size_t... I>(std::index_sequence<I...>) {
35 if constexpr (sizeof...(_descriptors) > 1)
36 for (size_t i : {I...})
37 for (size_t j : {I...})
38 if (i != j && strings_equal(names[i], names[j])) return false;
39 return true;
40 }(std::make_index_sequence<sizeof...(_descriptors)>{}),
41 "Names of a SubDescriptor must be unique!");
42
43 constexpr size_t get(const char *name) const
44 {
45 size_t running_sum = 0;
46 for (size_t i = 0; i < names.size(); ++i) {
47 if (0 == std::strcmp(names[i], name)) return running_sum;
48 running_sum += sizes[i];
49 }
50 // produce a compile-time error if the name is not found in the list
51 return running_sum != total_size ? 0
52 : throw std::invalid_argument("SubDescriptor::get: Name \"" + std::string(name) +
53 "\" not found. Available names are: " +
54 ((std::string(_descriptors::name) + "; ") + ...));
55 }
56
57 constexpr size_t operator[](const char *name) const { return get(name); }
58 constexpr size_t operator()(const char *name) const { return get(name); }
59
60 constexpr char const *name(size_t index) const { return names[index]; }
61
62 constexpr std::array<const char *, sizeof...(_descriptors)> get_names() const { return names; }
63 static std::vector<std::string> get_names_vector() { return {names.begin(), names.end()}; }
64
65 constexpr size_t size(const char *name) const
66 {
67 for (size_t i = 0; i < names.size(); ++i)
68 if (0 == std::strcmp(names[i], name)) return sizes[i];
69 }
70 };
71
72 template <typename... descriptors> using FEFunctionDescriptor = SubDescriptor<descriptors...>;
73 template <typename... descriptors> using VariableDescriptor = SubDescriptor<descriptors...>;
74 template <typename... descriptors> using ExtractorDescriptor = SubDescriptor<descriptors...>;
75
83 template <typename _FEFunctionDescriptor, typename _VariableDescriptor = VariableDescriptor<>,
84 typename _ExtractorDescriptor = ExtractorDescriptor<>, typename... LDGDescriptors>
86 {
87 using CouplingList = std::vector<std::array<uint, 2>>;
88
89 public:
90 using FEFunction_Descriptor = _FEFunctionDescriptor;
91 using Variable_Descriptor = _VariableDescriptor;
92 using Extractor_Descriptor = _ExtractorDescriptor;
93
94 private:
95 static constexpr uint n_fe_subsystems = sizeof...(LDGDescriptors) + 1;
96 static constexpr std::array<uint, n_fe_subsystems> n_components{
97 {FEFunction_Descriptor::total_size, LDGDescriptors::total_size...}};
98 static constexpr uint n_variables = Variable_Descriptor::total_size;
99 static constexpr uint n_extractors = Extractor_Descriptor::total_size;
100
101 public:
103 {
104 for (auto &dep : j_const)
105 for (auto &indep : dep)
106 indep = false;
107 }
108
117 void add_dependency(uint dependent_subsystem, uint dependent, uint independent_subsystem, uint independent)
118 {
119 if (dependent_subsystem >= n_fe_subsystems || independent_subsystem >= n_fe_subsystems)
120 throw std::runtime_error("The subsystems described by 'add_dependency' do not exist.");
121
122 if (dependent_subsystem != independent_subsystem + 1)
123 throw std::runtime_error(
124 "The model should only specify dependencies between fe subsystems at neighboring levels.");
125
126 couplings[dependent_subsystem][independent_subsystem].push_back({{dependent, independent}});
127
128 if (independent_subsystem > 0) {
129 for (const auto &dependency : couplings[independent_subsystem][independent_subsystem - 1])
130 if (dependency[0] == independent)
131 couplings[dependent_subsystem][independent_subsystem - 1].push_back({{dependent, dependency[1]}});
132 }
133 }
134
135 void set_jacobian_constant(uint dependent_subsystem, uint independent_subsystem)
136 {
137 if (dependent_subsystem >= n_fe_subsystems || independent_subsystem >= n_fe_subsystems)
138 throw std::runtime_error("The subsystems described by 'add_dependency' do not exist.");
139
140 if (dependent_subsystem != independent_subsystem + 1)
141 throw std::runtime_error(
142 "The model should only specify dependencies between fe subsystems at neighboring levels.");
143 j_const[dependent_subsystem][independent_subsystem] = true;
144
145 if (independent_subsystem > 0)
146 if (j_const[independent_subsystem][independent_subsystem - 1])
147 j_const[dependent_subsystem][independent_subsystem - 1] = true;
148 }
149
150 const CouplingList &ldg_couplings(uint dependent_subsystem, uint independent_subsystem) const
151 {
152 return couplings[dependent_subsystem][independent_subsystem];
153 }
154 bool jacobians_constant(uint dependent_subsystem, uint independent_subsystem) const
155 {
156 return j_const[dependent_subsystem][independent_subsystem];
157 }
158
159 static constexpr uint count_fe_functions(uint subsystem = 0) { return n_components[subsystem]; }
160 static constexpr uint count_variables() { return n_variables; }
161 static constexpr uint count_extractors() { return n_extractors; }
162 static constexpr uint count_fe_subsystems() { return n_fe_subsystems; }
163
164 template <typename DoFH> static std::vector<uint> get_component_block_structure(const DoFH &dofh)
165 {
166 std::vector<uint> dofs_per_component = dealii::DoFTools::count_dofs_per_fe_component(dofh);
167 return dofs_per_component;
168 }
169
170 private:
171 template <typename T> using SubsystemMatrix = std::array<std::array<T, n_fe_subsystems>, n_fe_subsystems>;
172
175 };
176} // namespace DiFfRG
A class to describe how many FE functions, additional variables and extractors are used in a model.
Definition component_descriptor.hh:86
ComponentDescriptor()
Definition component_descriptor.hh:102
_VariableDescriptor Variable_Descriptor
Definition component_descriptor.hh:91
void set_jacobian_constant(uint dependent_subsystem, uint independent_subsystem)
Definition component_descriptor.hh:135
static constexpr uint count_variables()
Definition component_descriptor.hh:160
SubsystemMatrix< bool > j_const
Definition component_descriptor.hh:174
static constexpr std::array< uint, n_fe_subsystems > n_components
Definition component_descriptor.hh:96
static constexpr uint count_fe_functions(uint subsystem=0)
Definition component_descriptor.hh:159
bool jacobians_constant(uint dependent_subsystem, uint independent_subsystem) const
Definition component_descriptor.hh:154
static constexpr uint count_extractors()
Definition component_descriptor.hh:161
const CouplingList & ldg_couplings(uint dependent_subsystem, uint independent_subsystem) const
Definition component_descriptor.hh:150
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:117
static constexpr uint n_extractors
Definition component_descriptor.hh:99
_ExtractorDescriptor Extractor_Descriptor
Definition component_descriptor.hh:92
static constexpr uint n_fe_subsystems
Definition component_descriptor.hh:95
std::array< std::array< T, n_fe_subsystems >, n_fe_subsystems > SubsystemMatrix
Definition component_descriptor.hh:171
static constexpr uint n_variables
Definition component_descriptor.hh:98
static std::vector< uint > get_component_block_structure(const DoFH &dofh)
Definition component_descriptor.hh:164
std::vector< std::array< uint, 2 > > CouplingList
Definition component_descriptor.hh:87
_FEFunctionDescriptor FEFunction_Descriptor
Definition component_descriptor.hh:90
static constexpr uint count_fe_subsystems()
Definition component_descriptor.hh:162
SubsystemMatrix< CouplingList > couplings
Definition component_descriptor.hh:173
Definition complex_math.hh:14
constexpr bool strings_equal(char const *a, char const *b)
Check if two strings are equal at compile time.
Definition tuples.hh:18
unsigned int uint
Definition utils.hh:22
A fixed size compile-time string.
Definition fixed_string.hh:10
Definition component_descriptor.hh:15
static constexpr size_t dim
Definition component_descriptor.hh:18
static constexpr FixedString name
Definition component_descriptor.hh:16
static constexpr std::array< size_t, dim > nd_sizes
Definition component_descriptor.hh:19
static constexpr size_t size
Definition component_descriptor.hh:17
Definition component_descriptor.hh:25
constexpr size_t size(const char *name) const
Definition component_descriptor.hh:65
constexpr size_t get(const char *name) const
Definition component_descriptor.hh:43
static std::vector< std::string > get_names_vector()
Definition component_descriptor.hh:63
static constexpr std::array< const char *, sizeof...(_descriptors)> names
Definition component_descriptor.hh:26
static constexpr size_t total_size
Definition component_descriptor.hh:30
constexpr size_t operator()(const char *name) const
Definition component_descriptor.hh:58
constexpr char const * name(size_t index) const
Definition component_descriptor.hh:60
constexpr std::array< const char *, sizeof...(_descriptors)> get_names() const
Definition component_descriptor.hh:62
static constexpr std::array< size_t, sizeof...(_descriptors)> sizes
Definition component_descriptor.hh:27
constexpr size_t operator[](const char *name) const
Definition component_descriptor.hh:57
std::tuple< _descriptors... > descriptor_tuple
Definition component_descriptor.hh:28