87 std::cout <<
"Discretization<dim>::prepare()" << std::endl;
92 ExcMessage(
"The fully distributed mesh type does not support global "
93 "refinement. The geometry must create a properly refined "
99 bool initialized =
false;
100 for (
auto &it : geometry_list_)
101 if (it->name() == geometry_) {
102 selected_geometry_ = it;
109 ExcMessage(
"Could not find a geometry description with name \"" +
115 const auto smoothing =
116 dealii::Triangulation<dim>::limit_level_difference_at_vertices;
118 switch (mesh_type_) {
120 const auto settings = dealii::TriangulationDescription::Settings::
121 construct_multigrid_hierarchy;
122 auto triangulation = std::make_unique<
123 dealii::parallel::fullydistributed::Triangulation<dim>>(
124 mpi_ensemble_.ensemble_communicator());
125 triangulation->set_mesh_smoothing(smoothing);
126 triangulation->set_partitioner(
127 [](dealii::Triangulation<dim> &tria,
128 const unsigned int n_partitions) {
129 GridTools::partition_triangulation_zorder(n_partitions, tria);
132 triangulation_ = std::move(triangulation);
136 const auto settings = dealii::parallel::distributed::Triangulation<
137 dim>::Settings::construct_multigrid_hierarchy;
139 std::make_unique<dealii::parallel::distributed::Triangulation<dim>>(
140 mpi_ensemble_.ensemble_communicator(), smoothing, settings);
144 const auto settings =
static_cast<
145 typename dealii::parallel::shared::Triangulation<dim>::Settings
>(
146 dealii::parallel::shared::Triangulation<dim>::partition_auto |
147 dealii::parallel::shared::Triangulation<
148 dim>::construct_multigrid_hierarchy);
151 std::make_unique<dealii::parallel::shared::Triangulation<dim>>(
152 mpi_ensemble_.ensemble_communicator(),
160 mpi_ensemble_.n_ensemble_ranks() == 1,
162 "The serial triangulation can only be used for serial "
163 "computations. If you want to run simulations with more than one "
164 "rank per ensemble, then please set \"mesh type\" to one of the "
165 "parallel triangulations supported by deal.II"));
167 triangulation_ = std::make_unique<dealii::Triangulation<dim>>(smoothing);
177 auto &triangulation = *triangulation_;
178 selected_geometry_->create_coarse_triangulation(triangulation);
180 if (mesh_writeout_ && dealii::Utilities::MPI::this_mpi_process(
181 mpi_ensemble_.ensemble_communicator()) == 0) {
182#ifdef DEAL_II_GMSH_WITH_API
184 grid_out.write_msh(triangulation, base_name +
"-coarse_grid.msh");
187 GridOutFlags::Msh flags(
true,
true);
188 grid_out.set_flags(flags);
189 std::ofstream file(base_name +
"-coarse_grid.msh");
190 grid_out.write_msh(triangulation, file);
194 triangulation.refine_global(refinement_);
196 if (std::abs(mesh_distortion_) > 1.0e-10)
197 GridTools::distort_random(
198 mesh_distortion_, triangulation,
false, std::random_device()());
200 const auto fe_degree = polynomial_degree();
201 const auto mapping_degree = fe_degree;
202 const auto quadrature_degree = fe_degree + 1;
210 const auto collection_type =
211 selected_geometry_->populate_hp_collections(fe_degree, collection_);
213 switch (collection_type) {
219 Assert(collection_.mapping, dealii::ExcInternalError());
220 Assert(collection_.finite_element_cg, dealii::ExcInternalError());
221 Assert(collection_.finite_element_dg, dealii::ExcInternalError());
222 Assert(collection_.quadrature, dealii::ExcInternalError());
223 Assert(collection_.quadrature_high_order, dealii::ExcInternalError());
224 Assert(collection_.nodal_quadrature, dealii::ExcInternalError());
225 Assert(collection_.quadrature_1d, dealii::ExcInternalError());
226 Assert(collection_.nodal_quadrature_1d, dealii::ExcInternalError());
227 Assert(collection_.face_quadrature, dealii::ExcInternalError());
228 Assert(collection_.face_nodal_quadrature, dealii::ExcInternalError());
237 collection_.finite_element_cg =
238 std::make_unique<hp::FECollection<dim>>(FE_Q<dim>(fe_degree));
239 collection_.finite_element_dg =
240 std::make_unique<hp::FECollection<dim>>(FE_DGQ<dim>(fe_degree));
248 if (selected_geometry_->transformation()) {
249 mapping_cache_ = std::make_shared<MappingQCache<dim>>(mapping_degree);
250 auto mapping = std::make_unique<hp::MappingCollection<dim>>();
251 hp::Collection<Mapping<dim>> &base = *mapping;
252 base.push_back(mapping_cache_);
253 collection_.mapping = std::move(mapping);
255 collection_.mapping =
256 std::make_unique<dealii::hp::MappingCollection<dim>>(
257 MappingQ<dim>(mapping_degree));
260 collection_.quadrature = std::make_unique<hp::QCollection<dim>>(
261 QGauss<dim>(quadrature_degree));
262 collection_.quadrature_high_order =
263 std::make_unique<hp::QCollection<dim>>(
264 QGauss<dim>(quadrature_degree + 1));
265 collection_.nodal_quadrature = std::make_unique<hp::QCollection<dim>>(
266 QGaussLobatto<dim>(quadrature_degree));
267 collection_.quadrature_1d =
268 std::make_unique<hp::QCollection<1>>(QGauss<1>(quadrature_degree));
269 collection_.nodal_quadrature_1d = std::make_unique<hp::QCollection<1>>(
270 QGaussLobatto<1>(quadrature_degree));
271 using QCF = hp::QCollection<dim - 1>;
272 collection_.face_quadrature = std::make_unique<std::vector<QCF>>(
273 1, QCF(QGauss<dim - 1>(quadrature_degree)));
274 collection_.face_nodal_quadrature = std::make_unique<std::vector<QCF>>(
275 1, QCF(QGaussLobatto<dim - 1>(quadrature_degree)));
284 collection_.finite_element_cg =
285 std::make_unique<hp::FECollection<dim>>(FE_SimplexP<dim>(fe_degree));
286 collection_.finite_element_dg = std::make_unique<hp::FECollection<dim>>(
287 FE_SimplexDGP<dim>(fe_degree));
289 if (mapping_degree == 1) {
290#if DEAL_II_VERSION_GTE(9, 7, 0)
291 collection_.mapping =
292 std::make_unique<hp::MappingCollection<dim>>(MappingP1<dim>());
294 collection_.mapping = std::make_unique<hp::MappingCollection<dim>>(
295 MappingFE<dim>(FE_SimplexP<dim>(fe_degree)));
298 collection_.mapping = std::make_unique<hp::MappingCollection<dim>>(
299 MappingFE<dim>(FE_SimplexP<dim>(fe_degree)));
302 collection_.quadrature = std::make_unique<hp::QCollection<dim>>(
303 QGaussSimplex<dim>(quadrature_degree));
304 collection_.quadrature_high_order =
305 std::make_unique<hp::QCollection<dim>>(
306 QGaussSimplex<dim>(quadrature_degree + 1));
307#if DEAL_II_VERSION_GTE(9, 7, 0)
308 collection_.nodal_quadrature = std::make_unique<hp::QCollection<dim>>(
309 FETools::compute_nodal_quadrature(
310 FE_SimplexP<dim>(quadrature_degree)));
313 dealii::ExcMessage(
"Discretization: Simplex support requires "
314 "deal.II version 9.7.0 or newer"));
316 collection_.quadrature_1d = std::make_unique<hp::QCollection<1>>(
317 QGaussSimplex<1>(quadrature_degree));
318#if DEAL_II_VERSION_GTE(9, 7, 0)
319 collection_.nodal_quadrature_1d = std::make_unique<hp::QCollection<1>>(
320 QGaussLobatto<1>(quadrature_degree));
322 using QCF = hp::QCollection<dim - 1>;
323 collection_.face_quadrature = std::make_unique<std::vector<QCF>>(
324 1, QCF(QGaussSimplex<dim - 1>(quadrature_degree)));
325 if constexpr (dim == 1) {
326 collection_.face_nodal_quadrature = std::make_unique<std::vector<QCF>>(
327 1, QCF(QGaussLobatto<dim - 1>(quadrature_degree)));
329#if DEAL_II_VERSION_GTE(9, 7, 0)
330 const auto quadrature = FETools::compute_nodal_quadrature(
331 FE_SimplexP<dim - 1>(quadrature_degree));
332 collection_.face_nodal_quadrature =
333 std::make_unique<std::vector<QCF>>(1, QCF(quadrature));