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 INCLUDE_EXADG_OPERATORS_INTERIOR_PENALTY_PARAMETER_H_
23#define INCLUDE_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].template get_gauss_type_quadrature<dim>(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).template get_gauss_type_quadrature<dim - 1>(degree +
66 1);
67 dealii::FEFaceValues<dim> fe_face_values(mapping, fe, face_quadrature, dealii::update_JxW_values);
68
69 for(unsigned int i = 0; i < n_cells; ++i)
70 {
71 for(unsigned int v = 0; v < matrix_free.n_active_entries_per_cell_batch(i); ++v)
72 {
73 typename dealii::DoFHandler<dim>::cell_iterator cell =
74 matrix_free.get_cell_iterator(i, v, dof_index);
75 fe_values.reinit(cell);
76
77 // calculate cell volume
78 Number volume = 0;
79 for(unsigned int q = 0; q < quadrature.size(); ++q)
80 {
81 volume += fe_values.JxW(q);
82 }
83
84 // calculate surface area
85 Number surface_area = 0;
86 for(unsigned int const f : cell->face_indices())
87 {
88 fe_face_values.reinit(cell, f);
89 Number const factor =
90 (cell->at_boundary(f) and not(cell->has_periodic_neighbor(f))) ? 1. : 0.5;
91 for(unsigned int q = 0; q < face_quadrature.size(); ++q)
92 {
93 surface_area += fe_face_values.JxW(q) * factor;
94 }
95 }
96
97 array_penalty_parameter[i][v] = surface_area / volume;
98 }
99 }
100}
101
102/*
103 * This function returns the penalty factor of the interior penalty method for
104 * quadrilateral/hexahedral or for triangular/tetrahedral elements for a given
105 * polynomial degree of the shape functions, a specified penalty factor
106 * (scaling factor) and the dimension of the problem.
107 */
108
109template<int dim, typename Number>
110Number
111get_penalty_factor(unsigned int const degree, ElementType element_type, Number const factor = 1.0)
112{
113 if(element_type == ElementType::Simplex)
114 {
115 // use penalty factor for simplex elements according to K. Shahbazi, An explicit expression for
116 // the penalty parameter of the interior penalty method, Journal of Computational Physics 205,
117 // 401–407, 2005.
118 return factor * (degree + 1.0) * (degree + dim) / dim;
119 }
120 else if(element_type == ElementType::Hypercube)
121 {
122 // use penalty factor for hypercube elements according to K. Hillewaert, Development of the
123 // discontinuous Galerkin method for high-resolution, large scale CFD and acoustics in
124 // industrial geometries, PhD thesis, Univ. de Louvain, 2013.
125 return factor * (degree + 1.0) * (degree + 1.0);
126 }
127 else
128 AssertThrow(false, dealii::ExcMessage("Only hypercube or simplex elements are supported."));
129}
130
131} // namespace IP
132} // namespace ExaDG
133
134
135#endif /* INCLUDE_EXADG_OPERATORS_INTERIOR_PENALTY_PARAMETER_H_ */
Definition driver.cpp:33