hyper.deal
Loading...
Searching...
No Matches
shape_info.h
1#ifndef HYPERDEAL_NDIM_MATRIXFREE_SHAPE_INFO
2#define HYPERDEAL_NDIM_MATRIXFREE_SHAPE_INFO
3
4#include <hyper.deal/base/config.h>
5
6#include <deal.II/base/geometry_info.h>
7
8namespace hyperdeal
9{
10 namespace internal
11 {
12 namespace MatrixFreeFunctions
13 {
17 template <typename Number>
18 struct ShapeInfo
19 {
25 template <int dim_x, int dim_v>
26 void
27 reinit(const unsigned int degree);
28
29 std::size_t
30 memory_consumption() const
31 {
32 return dealii::MemoryConsumption::memory_consumption(
34 }
35
39 dealii::types::global_dof_index dofs_per_cell;
40
44 dealii::types::global_dof_index dofs_per_face;
45
53 std::vector<std::vector<unsigned int>> face_to_cell_index_nodal;
54
58 std::vector<std::vector<unsigned int>> face_orientations;
59 };
60
61 namespace
62 {
63 template <int dim>
64 void
65 fill_face_to_cell_index_nodal(
66 const unsigned int points,
67 dealii::Table<2, unsigned int> &face_to_cell_index_nodal)
68 {
69 // adopted from dealii::internal::ShapeInfo::reinit()
70
71#ifdef DEBUG
72 const unsigned int dofs_per_component_on_cell =
73 dealii::Utilities::pow(points, dim);
74#endif
75 const unsigned int dofs_per_component_on_face =
76 dealii::Utilities::pow(points, dim - 1);
77 face_to_cell_index_nodal.reinit(
78 dealii::GeometryInfo<dim>::faces_per_cell,
79 dofs_per_component_on_face);
80 for (const auto f : dealii::GeometryInfo<dim>::face_indices())
81 {
82 const unsigned int direction = f / 2;
83 const unsigned int stride = direction < dim - 1 ? points : 1;
84 int shift = 1;
85 for (unsigned int d = 0; d < direction; ++d)
86 shift *= points;
87 const unsigned int offset = (f % 2) * (points - 1) * shift;
88
89 if (direction == 0 || direction == dim - 1)
90 for (unsigned int i = 0; i < dofs_per_component_on_face; ++i)
91 face_to_cell_index_nodal(f, i) = offset + i * stride;
92 else
93 // local coordinate system on faces 2 and 3 is zx in
94 // deal.II, not xz as expected for tensor products -> adjust
95 // that here
96 for (unsigned int j = 0; j < points; ++j)
97 for (unsigned int i = 0; i < points; ++i)
98 {
99 const unsigned int ind =
100 offset + j * dofs_per_component_on_face + i;
101 AssertIndexRange(ind, dofs_per_component_on_cell);
102 const unsigned int l = i * points + j;
103 face_to_cell_index_nodal(f, l) = ind;
104 }
105 }
106 }
107 } // namespace
108
109 template <typename Number>
110 template <int dim_x, int dim_v>
111 void
112 ShapeInfo<Number>::reinit(const unsigned int degree)
113 {
114 const unsigned int dim = dim_x + dim_v;
115 const unsigned int points = degree + 1;
116
117 this->dofs_per_cell = dealii::Utilities::pow(points, dim);
118 this->dofs_per_face = dealii::Utilities::pow(points, dim - 1);
119
120 const unsigned int dofs_per_component_on_face =
121 dealii::Utilities::pow(points, dim - 1);
122
123 face_to_cell_index_nodal.resize(
124 dealii::GeometryInfo<dim>::faces_per_cell);
125
126 dealii::Table<2, unsigned int> face_to_cell_index_nodal_x;
127 dealii::Table<2, unsigned int> face_to_cell_index_nodal_v;
128
129 fill_face_to_cell_index_nodal<dim_x>(points,
130 face_to_cell_index_nodal_x);
131 fill_face_to_cell_index_nodal<dim_v>(points,
132 face_to_cell_index_nodal_v);
133
134 for (unsigned int surface = 0;
135 surface < dealii::GeometryInfo<dim>::faces_per_cell;
136 surface++)
137 {
138 face_to_cell_index_nodal[surface].resize(
139 dofs_per_component_on_face);
140
141 if (surface < dim_x * 2)
142 for (unsigned int i = 0, k = 0;
143 i < dealii::Utilities::pow(points, dim_v);
144 i++)
145 for (unsigned int j = 0;
146 j < dealii::Utilities::pow(points, dim_x - 1);
147 j++)
148 face_to_cell_index_nodal[surface][k++] =
149 face_to_cell_index_nodal_x(surface, j) +
150 dealii::Utilities::pow(points, dim_x) * i;
151 else
152 for (unsigned int i = 0, k = 0;
153 i < dealii::Utilities::pow(points, dim_v - 1);
154 i++)
155 for (unsigned int j = 0;
156 j < dealii::Utilities::pow(points, dim_x);
157 j++)
158 face_to_cell_index_nodal[surface][k++] =
159 j + dealii::Utilities::pow(points, dim_x) *
160 face_to_cell_index_nodal_v(surface - 2 * dim_x, i);
161 }
162
163 // clang-format off
164 if (dim_x == 3 || dim_v == 3)
165 {
166 const unsigned int n = degree + 1;
167
168 face_orientations.resize( 16, std::vector<unsigned int>(this->dofs_per_face));
169
170 // x-space face
171 if (dim_x == 3)
172 for (unsigned int i = 0, c = 0; i < dealii::Utilities::pow(points, dim_v); ++i)
173 for (unsigned int j = 0; j < n; ++j)
174 for (unsigned int k = 0; k < n; ++k, ++c)
175 {
176 // face_orientation=true, face_flip=false, face_rotation=false
177 face_orientations[0][c] = c;
178 // face_orientation=false, face_flip=false, face_rotation=false
179 face_orientations[1][c] = j + k * n + i * dealii::Utilities::pow(points, 2);
180 // face_orientation=true, face_flip=true, face_rotation=false
181 face_orientations[2][c] = (n - 1 - k) + (n - 1 - j) * n + i * dealii::Utilities::pow(points, 2);
182 // face_orientation=false, face_flip=true, face_rotation=false
183 face_orientations[3][c] = (n - 1 - j) + (n - 1 - k) * n + i * dealii::Utilities::pow(points, 2);
184 // face_orientation=true, face_flip=false, face_rotation=true
185 face_orientations[4][c] = j + (n - 1 - k) * n + i * dealii::Utilities::pow(points, 2);
186 // face_orientation=false, face_flip=false, face_rotation=true
187 face_orientations[5][c] = k + (n - 1 - j) * n + i * dealii::Utilities::pow(points, 2);
188 // face_orientation=true, face_flip=true, face_rotation=true
189 face_orientations[6][c] = (n - 1 - j) + k * n + i * dealii::Utilities::pow(points, 2);
190 // face_orientation=false, face_flip=true, face_rotation=true
191 face_orientations[7][c] = (n - 1 - k) + j * n + i * dealii::Utilities::pow(points, 2);
192 }
193 else
194 for (unsigned int c = 0; c < dealii::Utilities::pow(points, dim - 1); ++c)
195 for (unsigned int i = 0; i < 8; ++i)
196 face_orientations[i][c] = c;
197
198 // v-space face
199 if (dim_v == 3)
200 for (unsigned int j = 0, c = 0; j < n; ++j)
201 for (unsigned int k = 0; k < n; ++k)
202 for (unsigned int i = 0; i < dealii::Utilities::pow(points, dim_x); ++i, ++c)
203 {
204 // face_orientation=true, face_flip=false, face_rotation=false
205 face_orientations[8][c] = c;
206 // face_orientation=false, face_flip=false, face_rotation=false
207 face_orientations[9][c] = (j + k * n) * dealii::Utilities::pow(points, dim_x) + i;
208 // face_orientation=true, face_flip=true, face_rotation=false
209 face_orientations[10][c] = ((n - 1 - k) + (n - 1 - j) * n) * dealii::Utilities::pow(points, dim_x) + i;
210 // face_orientation=false, face_flip=true, face_rotation=false
211 face_orientations[11][c] = ((n - 1 - j) + (n - 1 - k) * n) * dealii::Utilities::pow(points, dim_x) + i;
212 // face_orientation=true, face_flip=false, face_rotation=true
213 face_orientations[12][c] = (j + (n - 1 - k) * n) * dealii::Utilities::pow(points, dim_x) + i;
214 // face_orientation=false, face_flip=false, face_rotation=true
215 face_orientations[13][c] = (k + (n - 1 - j) * n) * dealii::Utilities::pow(points, dim_x) + i;
216 // face_orientation=true, face_flip=true, face_rotation=true
217 face_orientations[14][c] = ((n - 1 - j) + k * n) * dealii::Utilities::pow(points, dim_x) + i;
218 // face_orientation=false, face_flip=true, face_rotation=true
219 face_orientations[15][c] = ((n - 1 - k) + j * n) * dealii::Utilities::pow(points, dim_x) + i;
220 }
221 else
222 for (unsigned int c = 0; c < dealii::Utilities::pow(points, dim - 1); ++c)
223 for (unsigned int i = 8; i < 16; ++i)
224 face_orientations[i][c] = c;
225 }
226 else
227 {
228 face_to_cell_index_nodal.resize(16, std::vector<unsigned int>(1));
229 }
230 // clang-format on
231 }
232
233
234 } // namespace MatrixFreeFunctions
235 } // namespace internal
236} // namespace hyperdeal
237
238#endif
std::vector< std::vector< unsigned int > > face_orientations
Definition shape_info.h:58
void reinit(const unsigned int degree)
Definition shape_info.h:112
std::vector< std::vector< unsigned int > > face_to_cell_index_nodal
Definition shape_info.h:53
dealii::types::global_dof_index dofs_per_cell
Definition shape_info.h:39
dealii::types::global_dof_index dofs_per_face
Definition shape_info.h:44