ExaDG
Loading...
Searching...
No Matches
interior_penalty_parameter.h
1/* ______________________________________________________________________
2 *
3 * ExaDG - High-Order Discontinuous Galerkin for the Exa-Scale
4 *
5 * Copyright (C) 2021 by the ExaDG authors
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 * ______________________________________________________________________
20 */
21
22#ifndef EXADG_OPERATORS_INTERIOR_PENALTY_PARAMETER_H_
23#define EXADG_OPERATORS_INTERIOR_PENALTY_PARAMETER_H_
24
25// deal.II
26#include <deal.II/base/aligned_vector.h>
27#include <deal.II/base/vectorization.h>
28#include <deal.II/fe/mapping.h>
29#include <deal.II/matrix_free/fe_evaluation.h>
30#include <deal.II/matrix_free/matrix_free.h>
31
32// ExaDG
33#include <exadg/grid/grid_data.h>
34
35namespace ExaDG
36{
37namespace IP // IP = interior penalty
38{
39/*
40 * This function calculates the penalty parameter of the interior
41 * penalty method for each cell.
42 */
43template<int dim, typename Number>
44void
45calculate_penalty_parameter(
46 dealii::AlignedVector<dealii::VectorizedArray<Number>> & array_penalty_parameter,
47 dealii::MatrixFree<dim, Number> const & matrix_free,
48 unsigned int const dof_index = 0)
49{
50 unsigned int n_cells = matrix_free.n_cell_batches() + matrix_free.n_ghost_cell_batches();
51 array_penalty_parameter.resize(n_cells);
52
53 dealii::Mapping<dim> const & mapping = *matrix_free.get_mapping_info().mapping;
54 dealii::FiniteElement<dim> const & fe = matrix_free.get_dof_handler(dof_index).get_fe();
55 unsigned int const degree = fe.degree;
56
57 auto const reference_cells =
58 matrix_free.get_dof_handler(dof_index).get_triangulation().get_reference_cells();
59 AssertThrow(reference_cells.size() == 1, dealii::ExcMessage("No mixed meshes allowed."));
60
61 auto const quadrature = reference_cells[0].get_gauss_type_quadrature(degree + 1);
62 dealii::FEValues<dim> fe_values(mapping, fe, quadrature, dealii::update_JxW_values);
63
64 auto const face_quadrature =
65 reference_cells[0].face_reference_cell(0).get_gauss_type_quadrature(degree + 1);
66 dealii::FEFaceValues<dim> fe_face_values(mapping, fe, face_quadrature, dealii::update_JxW_values);
67
68 for(unsigned int i = 0; i < n_cells; ++i)
69 {
70 for(unsigned int v = 0; v < matrix_free.n_active_entries_per_cell_batch(i); ++v)
71 {
72 typename dealii::DoFHandler<dim>::cell_iterator cell =
73 matrix_free.get_cell_iterator(i, v, dof_index);
74 fe_values.reinit(cell);
75
76 // calculate cell volume
77 Number volume = 0;
78 for(unsigned int q = 0; q < quadrature.size(); ++q)
79 {
80 volume += fe_values.JxW(q);
81 }
82
83 // calculate surface area
84 Number surface_area = 0;
85 for(unsigned int const f : cell->face_indices())
86 {
87 fe_face_values.reinit(cell, f);
88 Number const factor =
89 (cell->at_boundary(f) and not(cell->has_periodic_neighbor(f))) ? 1. : 0.5;
90 for(unsigned int q = 0; q < face_quadrature.size(); ++q)
91 {
92 surface_area += fe_face_values.JxW(q) * factor;
93 }
94 }
95
96 array_penalty_parameter[i][v] = surface_area / volume;
97 }
98 }
99}
100
101/*
102 * This function returns the penalty factor of the interior penalty method for
103 * quadrilateral/hexahedral or for triangular/tetrahedral elements for a given
104 * polynomial degree of the shape functions, a specified penalty factor
105 * (scaling factor) and the dimension of the problem.
106 */
107
108template<int dim, typename Number>
109Number
110get_penalty_factor(unsigned int const degree, ElementType element_type, Number const factor = 1.0)
111{
112 if(element_type == ElementType::Simplex)
113 {
114 // use penalty factor for simplex elements according to K. Shahbazi, An explicit expression for
115 // the penalty parameter of the interior penalty method, Journal of Computational Physics 205,
116 // 401–407, 2005.
117 return factor * (degree + 1.0) * (degree + dim) / dim;
118 }
119 else if(element_type == ElementType::Hypercube)
120 {
121 // use penalty factor for hypercube elements according to K. Hillewaert, Development of the
122 // discontinuous Galerkin method for high-resolution, large scale CFD and acoustics in
123 // industrial geometries, PhD thesis, Univ. de Louvain, 2013.
124 return factor * (degree + 1.0) * (degree + 1.0);
125 }
126 else
127 AssertThrow(false, dealii::ExcMessage("Only hypercube or simplex elements are supported."));
128}
129
130} // namespace IP
131} // namespace ExaDG
132
133#endif /* EXADG_OPERATORS_INTERIOR_PENALTY_PARAMETER_H_ */
Definition driver.cpp:33