ExaDG
Loading...
Searching...
No Matches
categorization.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 OPERATOR_BASE_CATEGORIZATION_H
23#define OPERATOR_BASE_CATEGORIZATION_H
24
25// deal.II
26#include <deal.II/grid/tria.h>
27
28namespace ExaDG
29{
30namespace Categorization
31{
32/*
33 * Adjust MatrixFree::AdditionalData such that
34 * 1) cells which have the same boundary IDs for all faces are put into the
35 * same category
36 * 2) cell based loops are enabled (incl. dealii::FEEvaluationBase::read_cell_data()
37 * for all neighboring cells)
38 */
39template<int dim, typename AdditionalData>
40void
41do_cell_based_loops(dealii::Triangulation<dim> const & tria,
42 AdditionalData & data,
43 unsigned int const level = dealii::numbers::invalid_unsigned_int)
44{
45 bool is_mg = (level != dealii::numbers::invalid_unsigned_int);
46
47 // ... create list for the category of each cell
48 if(is_mg)
49 data.cell_vectorization_category.resize(std::distance(tria.begin(level), tria.end(level)));
50 else
51 data.cell_vectorization_category.resize(tria.n_active_cells());
52
53 AssertThrow(tria.get_reference_cells().size() == 1,
54 dealii::ExcMessage("No mixed meshes allowed."));
55
56 AssertThrow(not tria.has_hanging_nodes(),
57 dealii::ExcMessage("Cell based face loops do not support locally refined meshes."));
58
59 unsigned int const n_faces_per_cell = tria.get_reference_cells()[0].n_faces();
60
61 // ... setup scaling factor
62 std::vector<unsigned int> factors(n_faces_per_cell);
63
64 std::map<unsigned int, unsigned int> bid_map;
65 for(unsigned int i = 0; i < tria.get_boundary_ids().size(); i++)
66 bid_map[tria.get_boundary_ids()[i]] = i + 1;
67
68 {
69 unsigned int bids = tria.get_boundary_ids().size() + 1;
70 int offset = 1;
71 for(unsigned int i = 0; i < n_faces_per_cell; i++, offset = offset * bids)
72 factors[i] = offset;
73 }
74
75 auto to_category = [&](auto & cell) {
76 unsigned int c_num = 0;
77 for(unsigned int i = 0; i < n_faces_per_cell; i++)
78 {
79 const auto face = *cell->face(i);
80 if(face.at_boundary())
81 c_num += factors[i] * bid_map[face.boundary_id()];
82 }
83 return c_num;
84 };
85
86 if(not is_mg)
87 {
88 for(auto cell = tria.begin_active(); cell != tria.end(); ++cell)
89 {
90 if(cell->is_locally_owned())
91 data.cell_vectorization_category[cell->active_cell_index()] = to_category(cell);
92 }
93 }
94 else
95 {
96 for(auto cell = tria.begin(level); cell != tria.end(level); ++cell)
97 {
98 if(cell->is_locally_owned_on_level())
99 data.cell_vectorization_category[cell->index()] = to_category(cell);
100 }
101 }
102
103 // ... finalize setup of matrix_free
104 data.hold_all_faces_to_owned_cells = true;
105 data.cell_vectorization_categories_strict = true;
106 data.mapping_update_flags_faces_by_cells =
107 data.mapping_update_flags_inner_faces | data.mapping_update_flags_boundary_faces;
108}
109
110} // namespace Categorization
111} // namespace ExaDG
112
113#endif
Definition driver.cpp:33