ryujin 2.1.1 revision 0348cbb53a3e4b1da2a4c037e81f88f2d21ce219
discretization.template.h
Go to the documentation of this file.
1//
2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3// Copyright (C) 2020 - 2023 by the ryujin authors
4//
5
6#pragma once
7
8#include <compile_time_options.h>
9
10#include "discretization.h"
11#include "geometry_library.h"
12
13#include <deal.II/base/quadrature_lib.h>
14#include <deal.II/fe/fe_dgq.h>
15#include <deal.II/fe/fe_q.h>
16#include <deal.II/fe/mapping_q.h>
17#include <deal.II/grid/grid_out.h>
18
19#include <random>
20
21namespace ryujin
22{
23 using namespace dealii;
24
25 template <int dim>
27 const std::string &subsection)
28 : ParameterAcceptor(subsection)
29 , mpi_ensemble_(mpi_ensemble)
30 {
31 /* Options: */
32
33 ansatz_ = Ansatz::cg_q1;
34 add_parameter("finite element ansatz",
35 ansatz_,
36 "The finite element ansatz used for discretization. valid "
37 "choices are cG Q1, cG Q2, cG Q3.");
38
39 geometry_ = "cylinder";
40 add_parameter("geometry",
41 geometry_,
42 "Name of the geometry used to create the mesh. Valid names "
43 "are given by any of the subsections defined below.");
44
45 refinement_ = 5;
46 add_parameter("mesh refinement",
47 refinement_,
48 "number of refinement of global refinement steps");
49
50 mesh_writeout_ = true;
51 add_parameter("mesh writeout",
52 mesh_writeout_,
53 "Write out shared coarse mesh to a GMSH *.msh file.");
54
55 mesh_distortion_ = 0.;
56 add_parameter(
57 "mesh distortion", mesh_distortion_, "Strength of mesh distortion");
58
59 Geometries::populate_geometry_list<dim>(geometry_list_, subsection);
60 }
61
62
63 template <int dim>
64 void Discretization<dim>::prepare(const std::string &base_name)
65 {
66#ifdef DEBUG_OUTPUT
67 std::cout << "Discretization<dim>::prepare()" << std::endl;
68#endif
69
70 const auto smoothing =
71 dealii::Triangulation<dim>::limit_level_difference_at_vertices;
72
73 if constexpr (have_distributed_triangulation<dim>) {
74 const auto settings =
75 Triangulation::Settings::construct_multigrid_hierarchy;
76 triangulation_ = std::make_unique<Triangulation>(
77 mpi_ensemble_.ensemble_communicator(), smoothing, settings);
78
79 } else {
80 const auto settings = static_cast<typename Triangulation::Settings>(
81 Triangulation::partition_auto |
82 Triangulation::construct_multigrid_hierarchy);
83 /* Beware of the boolean: */
84 triangulation_ =
85 std::make_unique<Triangulation>(mpi_ensemble_.ensemble_communicator(),
86 smoothing,
87 /*artificial cells*/ true,
88 settings);
89 }
90
91 auto &triangulation = *triangulation_;
92
93 {
94 bool initialized = false;
95 for (auto &it : geometry_list_)
96 if (it->name() == geometry_) {
97 it->create_triangulation(triangulation);
98 initialized = true;
99 break;
100 }
101
102 AssertThrow(
103 initialized,
104 ExcMessage("Could not find a geometry description with name \"" +
105 geometry_ + "\""));
106 }
107
108 if (mesh_writeout_ && dealii::Utilities::MPI::this_mpi_process(
109 mpi_ensemble_.ensemble_communicator()) == 0) {
110#ifdef DEAL_II_GMSH_WITH_API
111 GridOut grid_out;
112 grid_out.write_msh(triangulation, base_name + "-coarse_grid.msh");
113#else
114 GridOut grid_out;
115 GridOutFlags::Msh flags(/* write faces */ true, /* write lines */ true);
116 grid_out.set_flags(flags);
117 std::ofstream file(base_name + "-coarse_grid.msh");
118 grid_out.write_msh(triangulation, file);
119#endif
120 }
121
122 triangulation.refine_global(refinement_);
123
124 if (std::abs(mesh_distortion_) > 1.0e-10)
125 GridTools::distort_random(
126 mesh_distortion_, triangulation, false, std::random_device()());
127
128 switch (ansatz_) {
129 case Ansatz::cg_q1:
130 finite_element_ = std::make_unique<FE_Q<dim>>(1);
131 break;
132 case Ansatz::cg_q2:
133 finite_element_ = std::make_unique<FE_Q<dim>>(2);
134 break;
135 case Ansatz::cg_q3:
136 finite_element_ = std::make_unique<FE_Q<dim>>(3);
137 break;
138 case Ansatz::dg_q0:
139 finite_element_ = std::make_unique<FE_DGQ<dim>>(0);
140 break;
141 case Ansatz::dg_q1:
142 finite_element_ = std::make_unique<FE_DGQ<dim>>(1);
143 break;
144 case Ansatz::dg_q2:
145 finite_element_ = std::make_unique<FE_DGQ<dim>>(2);
146 break;
147 case Ansatz::dg_q3:
148 finite_element_ = std::make_unique<FE_DGQ<dim>>(3);
149 break;
150 }
151
152 switch (ansatz_) {
153 case Ansatz::dg_q0:
154 mapping_ = std::make_unique<MappingQ<dim>>(1);
155 quadrature_ = std::make_unique<QGauss<dim>>(1);
156 quadrature_1d_ = std::make_unique<QGauss<1>>(1);
157 face_quadrature_ = std::make_unique<QGauss<dim - 1>>(1);
158 if (dim > 1)
159 face_nodal_quadrature_ = std::make_unique<dealii::QMidpoint<dim - 1>>();
160 else
161 face_nodal_quadrature_ = std::make_unique<QGauss<dim - 1>>(1);
162 break;
163 case Ansatz::cg_q1:
164 [[fallthrough]];
165 case Ansatz::dg_q1:
166 mapping_ = std::make_unique<MappingQ<dim>>(1);
167 quadrature_ = std::make_unique<QGauss<dim>>(2);
168 quadrature_1d_ = std::make_unique<QGauss<1>>(2);
169 face_quadrature_ = std::make_unique<QGauss<dim - 1>>(2);
170 face_nodal_quadrature_ =
171 std::make_unique<dealii::QGaussLobatto<dim - 1>>(2);
172 break;
173 case Ansatz::cg_q2:
174 [[fallthrough]];
175 case Ansatz::dg_q2:
176 mapping_ = std::make_unique<MappingQ<dim>>(2);
177 quadrature_ = std::make_unique<QGauss<dim>>(3);
178 quadrature_1d_ = std::make_unique<QGauss<1>>(3);
179 face_quadrature_ = std::make_unique<QGauss<dim - 1>>(3);
180 face_nodal_quadrature_ =
181 std::make_unique<dealii::QGaussLobatto<dim - 1>>(3);
182 break;
183 case Ansatz::cg_q3:
184 [[fallthrough]];
185 case Ansatz::dg_q3:
186 mapping_ = std::make_unique<MappingQ<dim>>(3);
187 quadrature_ = std::make_unique<QGauss<dim>>(4);
188 quadrature_1d_ = std::make_unique<QGauss<1>>(4);
189 face_quadrature_ = std::make_unique<QGauss<dim - 1>>(4);
190 face_nodal_quadrature_ =
191 std::make_unique<dealii::QGaussLobatto<dim - 1>>(4);
192 break;
193 }
194 }
195
196} /* namespace ryujin */
Discretization(const MPIEnsemble &mpi_ensemble, const std::string &subsection="/Discretization")
void prepare(const std::string &base_name)