8#include <boost/random/detail/polynomial.hpp>
9#include <compile_time_options.h>
14#include <deal.II/base/quadrature_lib.h>
15#include <deal.II/fe/fe_dgq.h>
16#include <deal.II/fe/fe_nothing.h>
17#include <deal.II/fe/fe_q.h>
18#include <deal.II/fe/fe_simplex_p.h>
19#include <deal.II/fe/fe_tools.h>
20#include <deal.II/fe/mapping_fe.h>
21#include <deal.II/fe/mapping_q.h>
22#include <deal.II/grid/grid_out.h>
28 using namespace dealii;
32 const std::string &subsection)
33 : ParameterAcceptor(subsection)
34 , mpi_ensemble_(mpi_ensemble)
39 add_parameter(
"finite element ansatz",
41 "The finite element ansatz used for discretization. Valid "
42 "choices are cG Q1, cG Q2, cG Q3.");
46 add_parameter(
"mesh type",
48 "The triangulation class used. Valid choices are \"serial\", "
49 "\"parallel shared\", \"parallel distributed\", \"parallel "
50 "fullydistributed\".");
52 if constexpr (dim == 1) {
53 geometry_ =
"rectangular domain";
55 geometry_ =
"cylinder";
57 add_parameter(
"geometry",
59 "Name of the geometry used to create the mesh. Valid names "
60 "are given by any of the subsections defined below.");
63 add_parameter(
"mesh refinement",
65 "number of refinement of global refinement steps");
67 mesh_writeout_ =
true;
68 add_parameter(
"mesh writeout",
70 "Write out shared coarse mesh to a GMSH *.msh file.");
72 mesh_distortion_ = 0.;
74 "mesh distortion", mesh_distortion_,
"Strength of mesh distortion");
76 Geometries::populate_geometry_list<dim>(geometry_list_, subsection);
84 std::cout <<
"Discretization<dim>::prepare()" << std::endl;
90 bool initialized =
false;
91 for (
auto &it : geometry_list_)
92 if (it->name() == geometry_) {
93 selected_geometry_ = it;
100 ExcMessage(
"Could not find a geometry description with name \"" +
106 const auto smoothing =
107 dealii::Triangulation<dim>::limit_level_difference_at_vertices;
109 switch (mesh_type_) {
111 triangulation_ = std::make_unique<
112 dealii::parallel::fullydistributed::Triangulation<dim>>(
113 mpi_ensemble_.ensemble_communicator());
114 triangulation_->set_mesh_smoothing(smoothing);
118 const auto settings = dealii::parallel::distributed::Triangulation<
119 dim>::Settings::construct_multigrid_hierarchy;
121 std::make_unique<dealii::parallel::distributed::Triangulation<dim>>(
122 mpi_ensemble_.ensemble_communicator(), smoothing, settings);
126 const auto settings =
static_cast<
127 typename dealii::parallel::shared::Triangulation<dim>::Settings
>(
128 dealii::parallel::shared::Triangulation<dim>::partition_auto |
129 dealii::parallel::shared::Triangulation<
130 dim>::construct_multigrid_hierarchy);
133 std::make_unique<dealii::parallel::shared::Triangulation<dim>>(
134 mpi_ensemble_.ensemble_communicator(),
142 mpi_ensemble_.n_ensemble_ranks() == 1,
144 "The serial triangulation can only be used for serial "
145 "computations. If you want to run simulations with more than one "
146 "rank per ensemble, then please set \"mesh type\" to one of the "
147 "parallel triangulations supported by deal.II"));
149 triangulation_ = std::make_unique<dealii::Triangulation<dim>>(smoothing);
159 auto &triangulation = *triangulation_;
160 selected_geometry_->create_coarse_triangulation(triangulation);
162 if (mesh_writeout_ && dealii::Utilities::MPI::this_mpi_process(
163 mpi_ensemble_.ensemble_communicator()) == 0) {
164#ifdef DEAL_II_GMSH_WITH_API
166 grid_out.write_msh(triangulation, base_name +
"-coarse_grid.msh");
169 GridOutFlags::Msh flags(
true,
true);
170 grid_out.set_flags(flags);
171 std::ofstream file(base_name +
"-coarse_grid.msh");
172 grid_out.write_msh(triangulation, file);
176 triangulation.refine_global(refinement_);
178 if (std::abs(mesh_distortion_) > 1.0e-10)
179 GridTools::distort_random(
180 mesh_distortion_, triangulation,
false, std::random_device()());
182 const auto fe_degree = polynomial_degree();
183 const auto mapping_degree = fe_degree;
184 const auto quadrature_degree = fe_degree + 1;
192 const auto collection_type = selected_geometry_->populate_hp_collections(
193 fe_degree, have_discontinuous_ansatz(), collection_);
195 switch (collection_type) {
201 Assert(collection_.mapping, dealii::ExcInternalError());
202 Assert(collection_.finite_element, dealii::ExcInternalError());
203 Assert(collection_.finite_element_cg, dealii::ExcInternalError());
204 Assert(collection_.quadrature, dealii::ExcInternalError());
205 Assert(collection_.quadrature_high_order, dealii::ExcInternalError());
206 Assert(collection_.nodal_quadrature, dealii::ExcInternalError());
207 Assert(collection_.quadrature_1d, dealii::ExcInternalError());
208 Assert(collection_.face_quadrature, dealii::ExcInternalError());
209 Assert(collection_.face_nodal_quadrature, dealii::ExcInternalError());
218 if (have_discontinuous_ansatz()) {
219 collection_.finite_element =
220 std::make_unique<hp::FECollection<dim>>(FE_DGQ<dim>(fe_degree));
221 collection_.finite_element_cg =
222 std::make_unique<hp::FECollection<dim>>(FE_Q<dim>(fe_degree));
224 collection_.finite_element =
225 std::make_unique<hp::FECollection<dim>>(FE_Q<dim>(fe_degree));
226 collection_.finite_element_cg =
227 std::make_unique<hp::FECollection<dim>>(FE_Q<dim>(fe_degree));
230 collection_.mapping =
231 std::make_unique<dealii::hp::MappingCollection<dim>>(
232 MappingQ<dim>(mapping_degree));
234 collection_.quadrature = std::make_unique<hp::QCollection<dim>>(
235 QGauss<dim>(quadrature_degree));
236 collection_.quadrature_high_order =
237 std::make_unique<hp::QCollection<dim>>(
238 QGauss<dim>(quadrature_degree + 1));
239 collection_.nodal_quadrature = std::make_unique<hp::QCollection<dim>>(
240 QGaussLobatto<dim>(quadrature_degree));
241 collection_.quadrature_1d =
242 std::make_unique<hp::QCollection<1>>(QGauss<1>(quadrature_degree));
243 collection_.face_quadrature = std::make_unique<hp::QCollection<dim - 1>>(
244 QGauss<dim - 1>(quadrature_degree));
245 collection_.face_nodal_quadrature =
246 std::make_unique<hp::QCollection<dim - 1>>(
247 QGaussLobatto<dim - 1>(quadrature_degree));
256 if (have_discontinuous_ansatz()) {
257 collection_.finite_element = std::make_unique<hp::FECollection<dim>>(
258 FE_SimplexDGP<dim>(fe_degree));
259 collection_.finite_element_cg = std::make_unique<hp::FECollection<dim>>(
260 FE_SimplexP<dim>(fe_degree));
262 collection_.finite_element = std::make_unique<hp::FECollection<dim>>(
263 FE_SimplexP<dim>(fe_degree));
264 collection_.finite_element_cg = std::make_unique<hp::FECollection<dim>>(
265 FE_SimplexP<dim>(fe_degree));
268 collection_.mapping =
269 std::make_unique<dealii::hp::MappingCollection<dim>>(
270 MappingFE<dim>(FE_SimplexP<dim>(mapping_degree)));
272 collection_.quadrature = std::make_unique<hp::QCollection<dim>>(
273 QGaussSimplex<dim>(quadrature_degree));
274 collection_.quadrature_high_order =
275 std::make_unique<hp::QCollection<dim>>(
276 QGaussSimplex<dim>(quadrature_degree + 1));
277#if DEAL_II_VERSION_GTE(9, 7, 0)
278 collection_.nodal_quadrature = std::make_unique<hp::QCollection<dim>>(
279 FETools::compute_nodal_quadrature(FE_SimplexP<dim>(mapping_degree)));
282 dealii::ExcMessage(
"Discretization: Simplex support requires "
283 "deal.II version 9.7.0 or newer"));
286 collection_.quadrature_1d = std::make_unique<hp::QCollection<1>>(
287 QGaussSimplex<1>(quadrature_degree));
288 collection_.face_quadrature = std::make_unique<hp::QCollection<dim - 1>>(
289 QGaussSimplex<dim - 1>(quadrature_degree));
290 if constexpr (dim == 1) {
291 collection_.face_nodal_quadrature =
292 std::make_unique<hp::QCollection<dim - 1>>(
293 QGaussLobatto<dim - 1>(quadrature_degree));
295#if DEAL_II_VERSION_GTE(9, 7, 0)
296 collection_.face_nodal_quadrature =
297 std::make_unique<hp::QCollection<dim - 1>>(
298 FETools::compute_nodal_quadrature(
299 FE_SimplexP<dim - 1>(mapping_degree)));
303 dealii::ExcMessage(
"Discretization: Simplex support requires "
304 "deal.II version 9.7.0 or newer"));
Discretization(const MPIEnsemble &mpi_ensemble, const std::string &subsection="/Discretization")
void prepare(const std::string &base_name)
@ parallel_fullydistributed