21 static constexpr int dim = dim_x + dim_v;
22 static constexpr unsigned int n_rows_of_product =
23 dealii::Utilities::pow(n_rows, dim);
24 static constexpr unsigned int n_columns_of_product =
25 dealii::Utilities::pow(n_columns, dim);
28 : shape_values(
nullptr)
29 , shape_gradients(
nullptr)
30 , shape_hessians(
nullptr)
34 const dealii::AlignedVector<Number2> &shape_values,
35 const dealii::AlignedVector<Number2> &shape_gradients,
36 const dealii::AlignedVector<Number2> &shape_hessians,
37 const unsigned int dummy1 = 0,
38 const unsigned int dummy2 = 0)
39 : shape_values(shape_values.begin())
40 , shape_gradients(shape_gradients.begin())
41 , shape_hessians(shape_hessians.begin())
47 Assert(shape_values.size() == 0 ||
48 shape_values.size() == n_rows * n_columns ||
49 shape_values.size() == 3 * n_rows,
50 dealii::ExcDimensionMismatch(shape_values.size(),
52 Assert(shape_gradients.size() == 0 ||
53 shape_gradients.size() == n_rows * n_columns,
54 dealii::ExcDimensionMismatch(shape_gradients.size(),
56 Assert(shape_hessians.size() == 0 ||
57 shape_hessians.size() == n_rows * n_columns,
58 dealii::ExcDimensionMismatch(shape_hessians.size(),
64 template <
int face_direction,
65 bool contract_onto_face,
69 apply_face_1D(
const Number *DEAL_II_RESTRICT in,
70 Number *DEAL_II_RESTRICT out,
71 const unsigned int in_index,
72 const unsigned int out_index)
const
74 constexpr int in_stride =
75 dealii::Utilities::pow(n_rows, face_direction);
76 constexpr int out_stride = dealii::Utilities::pow(n_rows, dim - 1);
78 const Number2 *DEAL_II_RESTRICT shape_values = this->shape_values;
80 if (contract_onto_face ==
true)
82 Number res0 = shape_values[0] * in[in_index + 0];
84 if (max_derivative > 0)
85 res1 = shape_values[n_rows] * in[in_index + 0];
86 if (max_derivative > 1)
87 res2 = shape_values[2 * n_rows] * in[in_index + 0];
88 for (
int ind = 1; ind < n_rows; ++ind)
90 res0 += shape_values[ind] * in[in_index + in_stride * ind];
91 if (max_derivative > 0)
93 shape_values[ind + n_rows] * in[in_index + in_stride * ind];
94 if (max_derivative > 1)
95 res2 += shape_values[ind + 2 * n_rows] *
96 in[in_index + in_stride * ind];
100 out[out_index + 0] += res0;
101 if (max_derivative > 0)
102 out[out_index + out_stride] += res1;
103 if (max_derivative > 1)
104 out[out_index + 2 * out_stride] += res2;
108 out[out_index + 0] = res0;
109 if (max_derivative > 0)
110 out[out_index + out_stride] = res1;
111 if (max_derivative > 1)
112 out[out_index + 2 * out_stride] = res2;
117 for (
int col = 0; col < n_rows; ++col)
120 out[in_index + col * in_stride] +=
121 shape_values[col] * in[out_index + 0];
123 out[in_index + col * in_stride] =
124 shape_values[col] * in[out_index + 0];
125 if (max_derivative > 0)
126 out[in_index + col * in_stride] +=
127 shape_values[col + n_rows] * in[out_index + out_stride];
128 if (max_derivative > 1)
129 out[in_index + col * in_stride] +=
130 shape_values[col + 2 * n_rows] *
131 in[out_index + 2 * out_stride];
136 template <
int face_direction,
137 bool contract_onto_face,
141 apply_face(
const Number *DEAL_II_RESTRICT in,
142 Number *DEAL_II_RESTRICT out)
const
144 static_assert(max_derivative >= 0 && max_derivative < 3,
145 "Only derivative orders 0-2 implemented");
146 Assert(shape_values !=
nullptr,
148 "The given array shape_values must not be the null pointer."));
150 AssertIndexRange(face_direction, dim);
152 using namespace dealii::Utilities;
154 if ((dim_x == 3) && (face_direction == 1))
156 for (
int i3 = 0; i3 < pow(n_rows, dim_v); ++i3)
157 for (
int i2 = 0; i2 < n_rows; ++i2)
158 for (
int i1 = 0; i1 < n_rows; ++i1)
160 const unsigned in_index =
161 i1 + i2 * pow(n_rows, 2) + i3 * pow(n_rows, 3);
164 const unsigned out_index =
165 i2 + i1 * n_rows + i3 * pow(n_rows, 2);
167 apply_face_1D<face_direction,
170 max_derivative>(in, out, in_index, out_index);
173 else if ((dim_v == 3) && (face_direction == (1 + dim_x)))
175 for (
int i3 = 0; i3 < n_rows; ++i3)
176 for (
int i2 = 0; i2 < n_rows; ++i2)
177 for (
int i1 = 0; i1 < pow(n_rows, dim_x); ++i1)
179 const unsigned in_index = i1 + i2 * pow(n_rows, dim_x) +
180 i3 * pow(n_rows, dim_x + 2);
183 const unsigned out_index = i1 + i3 * pow(n_rows, dim_x) +
184 i2 * pow(n_rows, dim_x + 1);
186 apply_face_1D<face_direction,
189 max_derivative>(in, out, in_index, out_index);
194 constexpr int n_blocks1 = pow(n_rows, face_direction);
195 constexpr int n_blocks2 =
196 pow(n_rows, std::max(dim - face_direction - 1, 0));
198 for (
int i2 = 0; i2 < n_blocks2; ++i2)
199 for (
int i1 = 0; i1 < n_blocks1; ++i1)
201 const unsigned in_index =
202 i1 + i2 * pow(n_rows, face_direction + 1);
203 const unsigned out_index =
204 i1 + i2 * pow(n_rows, face_direction);
206 apply_face_1D<face_direction,
209 max_derivative>(in, out, in_index, out_index);
215 const Number2 *shape_values;
216 const Number2 *shape_gradients;
217 const Number2 *shape_hessians;
223 static const int dim = dim_x + dim_v;
227 template <
bool do_evaluate,
bool add_
into_output,
typename Number2>
230 const unsigned int n_components,
231 const dealii::EvaluationFlags::EvaluationFlags flags,
232 const dealii::internal::MatrixFreeFunctions::ShapeInfo<Number>
234 const Number2 * input,
236 const unsigned int face_no)
238 Assert(
static_cast<unsigned int>(fe_degree + 1) ==
239 shape_info.data.front().n_q_points_1d ||
241 dealii::ExcInternalError());
243 interpolate_generic<do_evaluate, add_into_output>(
249 shape_info.data.front().quadrature.size(),
250 shape_info.data.front().quadrature_data_on_face,
251 shape_info.n_q_points,
252 shape_info.n_q_points_face);
256 template <
bool do_evaluate,
257 bool add_into_output,
258 int face_direction = 0,
262 const unsigned int n_components,
263 const Number2 * input,
265 const dealii::EvaluationFlags::EvaluationFlags flag,
266 const unsigned int face_no,
267 const unsigned int n_points_1d,
268 const std::array<dealii::AlignedVector<Number>, 2> &shape_data,
269 const unsigned int dofs_per_component_on_cell,
270 const unsigned int dofs_per_component_on_face)
272 if (face_direction == face_no / 2)
280 evalf(shape_data[face_no % 2],
281 dealii::AlignedVector<Number>(),
282 dealii::AlignedVector<Number>(),
286 const unsigned int in_stride = do_evaluate ?
287 dofs_per_component_on_cell :
288 dofs_per_component_on_face;
289 const unsigned int out_stride = do_evaluate ?
290 dofs_per_component_on_face :
291 dofs_per_component_on_cell;
293 for (
unsigned int c = 0; c < n_components; ++c)
295 if (flag & dealii::EvaluationFlags::hessians)
296 evalf.template apply_face<face_direction,
300 else if (flag & dealii::EvaluationFlags::gradients)
301 evalf.template apply_face<face_direction,
306 evalf.template apply_face<face_direction,
311 output += out_stride;
314 else if (face_direction < dim)
316 interpolate_generic<do_evaluate,
318 std::min(face_direction + 1, dim - 1)>(
326 dofs_per_component_on_cell,
327 dofs_per_component_on_face);