hyper.deal
Loading...
Searching...
No Matches
fe_evaluation_face.h
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2020 by the hyper.deal authors
4//
5// This file is part of the hyper.deal library.
6//
7// The hyper.deal library is free software; you can use it, redistribute
8// it, and/or modify it under the terms of the GNU Lesser General
9// Public License as published by the Free Software Foundation; either
10// version 3.0 of the License, or (at your option) any later version.
11// The full text of the license can be found in the file LICENSE.MD at
12// the top level directory of hyper.deal.
13//
14// ---------------------------------------------------------------------
15
16#ifndef HYPERDEAL_NDIM_FEEVALUATION_FACE
17#define HYPERDEAL_NDIM_FEEVALUATION_FACE
18
19#include <hyper.deal/base/config.h>
20
21#include <deal.II/matrix_free/fe_evaluation.h>
22
23#include <hyper.deal/matrix_free/fe_evaluation_base.h>
24#include <hyper.deal/matrix_free/read_write_operation.h>
25#include <hyper.deal/matrix_free/vector_access_internal.h>
26
27namespace hyperdeal
28{
35 template <int dim_x,
36 int dim_v,
37 int degree,
38 int n_points,
39 typename Number,
40 typename VectorizedArrayType>
41 class FEFaceEvaluation : public FEEvaluationBase<dim_x,
42 dim_v,
43 degree,
44 n_points,
45 Number,
46 VectorizedArrayType>
47 {
48 public:
49 static const unsigned int DIM = dim_x + dim_v;
50 static const unsigned int DIM_ = DIM;
51 static const unsigned int N_Q_POINTS =
52 dealii::Utilities::pow(n_points, DIM - 1);
53
54 static const unsigned int N_Q_POINTS_1_CELL =
55 dealii::Utilities::pow(n_points, dim_x - 0);
56 static const unsigned int N_Q_POINTS_2_CELL =
57 dealii::Utilities::pow(n_points, dim_v - 0);
58
59 static const unsigned int N_Q_POINTS_1_FACE =
60 dealii::Utilities::pow(n_points, dim_x - 1);
61 static const unsigned int N_Q_POINTS_2_FACE =
62 dealii::Utilities::pow(n_points, dim_v - 1);
63
64 using PARENT = FEEvaluationBase<dim_x,
65 dim_v,
66 degree,
67 n_points,
68 Number,
69 VectorizedArrayType>;
70
71 static const unsigned int n_vectors = PARENT::n_vectors;
72 static const unsigned int n_vectors_v = PARENT::n_vectors_v;
73
74 // clang-format off
75 static const unsigned int dim = dim_x + dim_v;
76 static const unsigned int static_dofs_per_cell = dealii::Utilities::pow(degree + 1, dim);
77 static const unsigned int static_dofs_per_cell_x = dealii::Utilities::pow(degree + 1, dim_x);
78 static const unsigned int static_dofs_per_cell_v = dealii::Utilities::pow(degree + 1, dim_v);
79 static const unsigned int static_dofs_per_face = dealii::Utilities::pow(degree + 1, dim_x + dim_v - 1);
80 // clang-format on
81
82 using SpaceType =
84 SpaceType;
85
111 const bool is_minus_face,
112 const unsigned int dof_no_x,
113 const unsigned int dof_no_v,
114 const unsigned int quad_no_x,
115 const unsigned int quad_no_v)
117 , is_minus_face(is_minus_face)
118 , phi_x(this->matrix_free_x, dof_no_x, quad_no_x)
119 , phi_v(this->matrix_free_v, dof_no_v, quad_no_v)
120 , phi_face_x(this->matrix_free_x, is_minus_face, dof_no_x, quad_no_x)
121 , phi_face_v(this->matrix_free_v, is_minus_face, dof_no_v, quad_no_v)
122 {
123 this->shape_values = &phi_x.get_shape_info().data[0].shape_values_eo;
124 this->shape_gradients =
125 &phi_x.get_shape_info().data[0].shape_gradients_collocation_eo;
126 }
127
128
129
133 void
135 face_index) override
136 {
137 PARENT::reinit(face_index);
138 this->type = face_index.type;
139 this->is_ecl = false;
140
141 if (this->type == SpaceType::X)
142 {
143 phi_face_x.reinit(this->macro_cell_x);
144 phi_v.reinit(this->macro_cell_v);
145 }
146 else
147 {
148 phi_x.reinit(this->macro_cell_x);
149 phi_face_v.reinit(this->macro_cell_v);
150 }
151
152 if (this->type == SpaceType::X)
153 {
154 this->n_filled_lanes =
155 this->matrix_free_x.n_active_entries_per_face_batch(
156 this->macro_cell_x);
157 }
158 else
159 {
160 this->n_filled_lanes =
161 this->matrix_free_x.n_active_entries_per_cell_batch(
162 this->macro_cell_x);
163 }
164
165 // get direction of face
166 if (type == SpaceType::X)
167 {
168 const dealii::internal::MatrixFreeFunctions::FaceToCellTopology<
169 n_vectors> &faces =
170 this->matrix_free_x.get_face_info(this->macro_cell_x);
171 this->face_no = this->is_minus_face ? faces.interior_face_no :
172 faces.exterior_face_no;
173 }
174 else
175 {
176 const dealii::internal::MatrixFreeFunctions::FaceToCellTopology<
177 n_vectors_v> &faces =
178 this->matrix_free_v.get_face_info(this->macro_cell_v);
179 this->face_no = this->is_minus_face ? faces.interior_face_no :
180 faces.exterior_face_no;
181 this->face_no += dim_x * 2;
182 }
183 }
184
185
186
190 void
192 cell_index,
193 unsigned int face)
194 {
195 PARENT::reinit(cell_index);
196 this->type = (face >= 2 * dim_x) ? SpaceType::V : SpaceType::X;
197 this->is_ecl = true;
198
199 // delegate reinit to deal.II data structures
200 if (this->type == SpaceType::X)
201 {
202 phi_face_x.reinit(this->macro_cell_x, face);
203 phi_v.reinit(this->macro_cell_v);
204 }
205 else
206 {
207 phi_x.reinit(this->macro_cell_x);
208 phi_face_v.reinit(this->macro_cell_v, face - 2 * dim_x);
209 }
210
211 // how many lanes are filled?
212 {
213 this->n_filled_lanes =
214 this->matrix_free_x.n_active_entries_per_cell_batch(
215 this->macro_cell_x);
216 }
217
218 // get direction of face
219 {
220 this->face_no = face;
221 }
222 }
223
224
225
229 void
231 const dealii::LinearAlgebra::distributed::Vector<Number> &src)
232 {
233 read_dof_values(src, &this->data[0]);
234 }
235
236
237
241 void
243 const dealii::LinearAlgebra::distributed::Vector<Number> &src,
244 VectorizedArrayType * data) const
245 {
247 {
248 // for comments see dealii::FEEvaluation::reinit
249 const unsigned int face_orientation =
250 is_ecl ? 0 :
251 ((this->is_minus_face ==
253 .face_orientations[0][this->macro] >= 8)) ?
255 .face_orientations[0][this->macro] %
256 8) :
257 0);
258
261 this->matrix_free.get_face_info(),
262 this->matrix_free.get_shape_info())
263 .template process_face<dim_x, dim_v, degree>(
264 internal::MatrixFreeFunctions::
265 VectorReader<Number, VectorizedArrayType>(),
266 src.shared_vector_data(),
267 data,
268 (is_ecl == false || this->is_minus_face) ?
269 &this->face_no :
270 this->matrix_free.get_face_info().no_faces[3].data() +
271 (2 * dim * this->macro + this->face_no) * n_vectors,
272 (is_ecl == false || this->is_minus_face) ?
273 &face_orientation :
274 this->matrix_free.get_face_info().face_orientations[3].data() +
275 (2 * dim * this->macro + this->face_no) * n_vectors,
276 this->type == SpaceType::X ? 0 : 8,
277 this->macro,
278 is_ecl ? 2 : !is_minus_face,
279 (is_ecl == false || this->is_minus_face) ?
280 this->macro :
281 2 * dim * this->macro + this->face_no,
282 !is_minus_face + (is_ecl ? 2 : 0));
283 }
284 else
285 {
286 AssertThrow(false, dealii::StandardExceptions::ExcNotImplemented());
287 }
288 }
289
290
291
292 /*
293 * Read the face data from a cell buffer held e.g. by FEEvaluation.
294 */
295 void
296 read_dof_values_from_buffer(const VectorizedArrayType *src)
297 {
298 const auto &index_array = this->matrix_free.get_shape_info()
299 .face_to_cell_index_nodal[this->face_no];
300
301 for (unsigned int i = 0; i < static_dofs_per_face; ++i)
302 this->data[i] = src[index_array[i]];
303 }
304
305
306
310 void
311 distribute_to_buffer(VectorizedArrayType *dst) const
312 {
313 const auto &index_array = this->matrix_free.get_shape_info()
314 .face_to_cell_index_nodal[this->face_no];
315
316 for (unsigned int i = 0; i < static_dofs_per_face; ++i)
317 dst[index_array[i]] += this->data[i];
318 }
319
320
324 void
326 dealii::LinearAlgebra::distributed::Vector<Number> &dst) const
327 {
328 Assert(is_ecl == false, dealii::StandardExceptions::ExcNotImplemented());
329
331 {
332 // for comments see dealii::FEEvaluation::reinit
333 const unsigned int face_orientation =
334 is_ecl ? 0 :
335 ((this->is_minus_face ==
337 .face_orientations[0][this->macro] >= 8)) ?
339 .face_orientations[0][this->macro] %
340 8) :
341 0);
342
345 this->matrix_free.get_face_info(),
346 this->matrix_free.get_shape_info())
347 .template process_face<dim_x, dim_v, degree>(
348 internal::MatrixFreeFunctions::
349 VectorDistributorLocalToGlobal<Number, VectorizedArrayType>(),
350 dst.shared_vector_data(),
351 &this->data[0],
352 &this->face_no,
353 &face_orientation,
354 this->type == SpaceType::X ? 0 : 8,
355 this->macro,
356 !is_minus_face,
357 this->macro,
358 !is_minus_face);
359 }
360 else
361 {
362 AssertThrow(false, dealii::StandardExceptions::ExcNotImplemented());
363 }
364 }
365
366
367
371 inline unsigned int
373 {
374 return n_filled_lanes;
375 }
376
377
381 template <SpaceType stype>
382 inline DEAL_II_ALWAYS_INLINE //
383 void
384 submit_value(VectorizedArrayType *__restrict data_ptr,
385 const VectorizedArrayType &value,
386 const unsigned int q,
387 const unsigned int qx,
388 const unsigned int qv) const
389 {
390 Assert(stype == this->type, dealii::ExcMessage("Types do not match!"));
391
392 // note: this if-statement is evaluated at compile time
393 if (stype == SpaceType::X)
394 data_ptr[q] = -value * phi_face_x.JxW(qx) *
395 phi_v.JxW(qv)[n_vectors_v == 1 ? 0 : this->lane_y];
396 else if (stype == SpaceType::V)
397 data_ptr[q] = -value * phi_x.JxW(qx) *
398 phi_face_v.JxW(qv)[n_vectors_v == 1 ? 0 : this->lane_y];
399 }
400
401
402
406 template <SpaceType stype>
407 inline DEAL_II_ALWAYS_INLINE //
408 void
409 submit_value(VectorizedArrayType *__restrict data_ptr_1,
410 VectorizedArrayType *__restrict data_ptr_2,
411 const VectorizedArrayType &value,
412 const unsigned int q,
413 const unsigned int q1,
414 const unsigned int q2) const
415 {
416 Assert(stype == this->type, dealii::ExcMessage("Types do not match!"));
417
418 // note: this if-statement is evaluated at compile time
419 const auto temp =
420 (stype == SpaceType::X) ?
421 (value * phi_face_x.JxW(q1) *
422 phi_v.JxW(q2)[n_vectors_v == 1 ? 0 : this->lane_y]) :
423 (value * phi_x.JxW(q1) *
424 phi_face_v.JxW(q2)[n_vectors_v == 1 ? 0 : this->lane_y]);
425 data_ptr_1[q] = -temp;
426 data_ptr_2[q] = +temp;
427 }
428
429
430
434 inline DEAL_II_ALWAYS_INLINE //
435 dealii::Tensor<1, dim_x, VectorizedArrayType>
436 get_normal_vector_x(const unsigned int qx) const
437 {
438 // TODO: assert that we have (face x cell)
439
440 return phi_face_x.get_normal_vector(qx);
441 }
442
443
444
448 inline DEAL_II_ALWAYS_INLINE //
449 dealii::Tensor<1, dim_v, VectorizedArrayType>
450 get_normal_vector_v(const unsigned int qv) const
451 {
452 // TODO: assert that we have (cell x face)
453
454 // here we unfortunately have to copy the content due to different data
455 // types!
456 // TODO: implement constructor VectorizedArray<Number,
457 // N>::VectorizedArray(VectorizedArray<Number, 1>)
458 dealii::Tensor<1, dim_v, VectorizedArrayType> result;
459 const auto temp = phi_face_v.get_normal_vector(qv);
460 for (auto i = 0u; i < dim_v; i++)
461 result[i] = temp[i][0];
462 return result;
463 }
464
465
466
472 inline dealii::Point<DIM, VectorizedArrayType>
473 get_quadrature_point(const unsigned int q) const
474 {
475 dealii::Point<DIM, VectorizedArrayType> temp;
476
477 if (type == SpaceType::X)
478 {
479 const auto t1 =
480 this->phi_face_x.quadrature_point(q % N_Q_POINTS_1_FACE);
481 for (int i = 0; i < dim_x; i++)
482 temp[i] = t1[i];
483 const auto t2 = this->phi_v.quadrature_point(q / N_Q_POINTS_1_FACE);
484 for (int i = 0; i < dim_v; i++)
485 temp[i + dim_x] = t2[i][n_vectors_v == 1 ? 0 : this->lane_y];
486 }
487 else
488 {
489 const auto t1 = this->phi_x.quadrature_point(q % N_Q_POINTS_1_CELL);
490 for (int i = 0; i < dim_x; i++)
491 temp[i] = t1[i];
492 const auto t2 =
493 this->phi_face_v.quadrature_point(q / N_Q_POINTS_1_CELL);
494 for (int i = 0; i < dim_v; i++)
495 temp[i + dim_x] = t2[i][n_vectors_v == 1 ? 0 : this->lane_y];
496 }
497
498 return temp;
499 }
500
501
505 template <SpaceType stype>
506 inline dealii::Point<dim, VectorizedArrayType>
507 get_quadrature_point(const unsigned int qx, const unsigned int qv) const
508 {
509 Assert(stype == this->type, dealii::ExcMessage("Types do not match!"));
510
511 dealii::Point<dim, VectorizedArrayType> temp;
512
513 if (stype == SpaceType::X)
514 {
515 const auto t1 = this->phi_face_x.quadrature_point(qx);
516 for (int i = 0; i < dim_x; i++)
517 temp[i] = t1[i];
518 const auto t2 = this->phi_v.quadrature_point(qv);
519 for (int i = 0; i < dim_v; i++)
520 temp[i + dim_x] = t2[i][n_vectors_v == 1 ? 0 : this->lane_y];
521 }
522 else
523 {
524 const auto t1 = this->phi_x.quadrature_point(qx);
525 for (int i = 0; i < dim_x; i++)
526 temp[i] = t1[i];
527 const auto t2 = this->phi_face_v.quadrature_point(qv);
528 for (int i = 0; i < dim_v; i++)
529 temp[i + dim_x] = t2[i][n_vectors_v == 1 ? 0 : this->lane_y];
530 }
531
532 return temp;
533 }
534
535 private:
539 const bool is_minus_face;
540
544 unsigned int n_filled_lanes;
545
549 bool is_ecl;
550
554 SpaceType type;
555
559 unsigned int face_no;
560
561 // clang-format off
562 dealii::FEEvaluation<dim_x, degree, n_points, 1, Number, typename PARENT::VectorizedArrayTypeX> phi_x;
563 dealii::FEEvaluation<dim_v, degree, n_points, 1, Number, typename PARENT::VectorizedArrayTypeV> phi_v;
564
565 dealii::FEFaceEvaluation<dim_x, degree, n_points, 1, Number, typename PARENT::VectorizedArrayTypeX> phi_face_x;
566 dealii::FEFaceEvaluation<dim_v, degree, n_points, 1, Number, typename PARENT::VectorizedArrayTypeV> phi_face_v;
567 // clang-format on
568 };
569
570} // namespace hyperdeal
571
572#endif
Definition fe_evaluation_base.h:35
virtual void reinit(typename MatrixFree< dim_x, dim_v, Number, VectorizedArrayType >::ID cell_index)
Definition fe_evaluation_base.h:168
const dealii::AlignedVector< Number > * shape_values
Definition fe_evaluation_base.h:122
dealii::AlignedVector< VectorizedArrayType > data
Definition fe_evaluation_base.h:93
const MF & matrix_free
Definition fe_evaluation_base.h:98
const dealii::MatrixFree< dim_v, Number, VectorizedArrayTypeV > & matrix_free_v
Definition fe_evaluation_base.h:110
const dealii::MatrixFree< dim_x, Number, VectorizedArrayTypeX > & matrix_free_x
Definition fe_evaluation_base.h:104
const dealii::AlignedVector< Number > * shape_gradients
Definition fe_evaluation_base.h:127
Definition fe_evaluation_face.h:47
void reinit(typename MatrixFree< dim_x, dim_v, Number, VectorizedArrayType >::ID cell_index, unsigned int face)
Definition fe_evaluation_face.h:191
void read_dof_values(const dealii::LinearAlgebra::distributed::Vector< Number > &src, VectorizedArrayType *data) const
Definition fe_evaluation_face.h:242
DEAL_II_ALWAYS_INLINE void submit_value(VectorizedArrayType *__restrict data_ptr, const VectorizedArrayType &value, const unsigned int q, const unsigned int qx, const unsigned int qv) const
Definition fe_evaluation_face.h:384
unsigned int n_vectorization_lanes_filled() const
Definition fe_evaluation_face.h:372
FEFaceEvaluation(const MatrixFree< dim_x, dim_v, Number, VectorizedArrayType > &matrix_free, const bool is_minus_face, const unsigned int dof_no_x, const unsigned int dof_no_v, const unsigned int quad_no_x, const unsigned int quad_no_v)
Definition fe_evaluation_face.h:109
void read_dof_values(const dealii::LinearAlgebra::distributed::Vector< Number > &src)
Definition fe_evaluation_face.h:230
dealii::Point< DIM, VectorizedArrayType > get_quadrature_point(const unsigned int q) const
Definition fe_evaluation_face.h:473
dealii::Point< dim, VectorizedArrayType > get_quadrature_point(const unsigned int qx, const unsigned int qv) const
Definition fe_evaluation_face.h:507
void distribute_local_to_global(dealii::LinearAlgebra::distributed::Vector< Number > &dst) const
Definition fe_evaluation_face.h:325
DEAL_II_ALWAYS_INLINE void submit_value(VectorizedArrayType *__restrict data_ptr_1, VectorizedArrayType *__restrict data_ptr_2, const VectorizedArrayType &value, const unsigned int q, const unsigned int q1, const unsigned int q2) const
Definition fe_evaluation_face.h:409
void reinit(typename MatrixFree< dim_x, dim_v, Number, VectorizedArrayType >::ID face_index) override
Definition fe_evaluation_face.h:134
DEAL_II_ALWAYS_INLINE dealii::Tensor< 1, dim_v, VectorizedArrayType > get_normal_vector_v(const unsigned int qv) const
Definition fe_evaluation_face.h:450
void distribute_to_buffer(VectorizedArrayType *dst) const
Definition fe_evaluation_face.h:311
DEAL_II_ALWAYS_INLINE dealii::Tensor< 1, dim_x, VectorizedArrayType > get_normal_vector_x(const unsigned int qx) const
Definition fe_evaluation_face.h:436
Definition matrix_free.h:40
const internal::MatrixFreeFunctions::DoFInfo & get_dof_info() const
Definition matrix_free.templates.h:1872
bool are_ghost_faces_supported() const
Definition matrix_free.templates.h:1835
const internal::MatrixFreeFunctions::FaceInfo & get_face_info() const
Definition matrix_free.templates.h:1881
const internal::MatrixFreeFunctions::ShapeInfo< Number > & get_shape_info() const
Definition matrix_free.templates.h:1890
Definition id.h:27
const SpaceType type
Definition id.h:69
std::array< std::vector< unsigned int >, 4 > face_orientations
Definition face_info.h:37