22#ifndef EXADG_GRID_GRID_UTILITIES_H_
23#define EXADG_GRID_GRID_UTILITIES_H_
26#include <deal.II/fe/fe_simplex_p.h>
27#include <deal.II/fe/mapping_fe.h>
28#include <deal.II/fe/mapping_q.h>
29#include <deal.II/grid/grid_in.h>
30#include <deal.II/grid/grid_tools.h>
31#include <deal.II/multigrid/mg_transfer_global_coarsening.h>
34#include <exadg/grid/balanced_granularity_partition_policy.h>
35#include <exadg/grid/grid.h>
36#include <exadg/grid/grid_data.h>
37#include <exadg/grid/perform_local_refinements.h>
41namespace GridUtilities
44using PeriodicFacePairs = std::vector<
45 dealii::GridTools::PeriodicFacePair<typename dealii::Triangulation<dim>::cell_iterator>>;
52create_mapping(std::shared_ptr<dealii::Mapping<dim>> & mapping,
53 ElementType
const & element_type,
54 unsigned int const & mapping_degree)
56 if(element_type == ElementType::Hypercube)
58 mapping = std::make_shared<dealii::MappingQ<dim>>(mapping_degree);
60 else if(element_type == ElementType::Simplex)
62 mapping = std::make_shared<dealii::MappingFE<dim>>(dealii::FE_SimplexP<dim>(mapping_degree));
66 AssertThrow(
false, dealii::ExcMessage(
"Invalid parameter element_type."));
76template<
int dim,
typename Number>
78create_mapping_with_multigrid(std::shared_ptr<dealii::Mapping<dim>> & mapping,
79 std::shared_ptr<MultigridMappings<dim, Number>> & multigrid_mappings,
80 ElementType
const & element_type,
81 unsigned int const & mapping_degree_fine,
82 unsigned int const & mapping_degree_coarse,
83 bool const involves_h_multigrid)
86 create_mapping(mapping, element_type, mapping_degree_fine);
89 std::shared_ptr<dealii::Mapping<dim>> coarse_mapping;
90 if(involves_h_multigrid and (mapping_degree_coarse != mapping_degree_fine))
92 create_mapping(coarse_mapping, element_type, mapping_degree_coarse);
94 multigrid_mappings = std::make_shared<MultigridMappings<dim, Number>>(mapping, coarse_mapping);
103std::vector<dealii::GridTools::PeriodicFacePair<typename dealii::DoFHandler<dim>::cell_iterator>>
104transform_periodic_face_pairs_to_dof_cell_iterator(
105 std::vector<dealii::GridTools::PeriodicFacePair<
106 typename dealii::Triangulation<dim>::cell_iterator>>
const & periodic_faces,
107 dealii::DoFHandler<dim>
const & dof_handler)
109 typedef typename std::vector<
110 dealii::GridTools::PeriodicFacePair<typename dealii::DoFHandler<dim>::cell_iterator>>
113 PeriodicFacesDoF periodic_faces_dof;
115 for(
auto it : periodic_faces)
117 dealii::GridTools::PeriodicFacePair<typename dealii::DoFHandler<dim>::cell_iterator>
118 face_pair_dof_hander;
120 face_pair_dof_hander.cell[0] = it.cell[0]->as_dof_handler_iterator(dof_handler);
121 face_pair_dof_hander.cell[1] = it.cell[1]->as_dof_handler_iterator(dof_handler);
123 face_pair_dof_hander.face_idx[0] = it.face_idx[0];
124 face_pair_dof_hander.face_idx[1] = it.face_idx[1];
126 face_pair_dof_hander.orientation = it.orientation;
127 face_pair_dof_hander.matrix = it.matrix;
129 periodic_faces_dof.push_back(face_pair_dof_hander);
132 return periodic_faces_dof;
146 std::shared_ptr<dealii::Triangulation<dim>> & triangulation,
147 PeriodicFacePairs<dim> & periodic_face_pairs,
148 MPI_Comm
const & mpi_comm,
149 GridData
const & data,
150 bool const construct_multigrid_hierarchy,
151 std::function<
void(dealii::Triangulation<dim> &,
152 PeriodicFacePairs<dim> &,
154 std::vector<unsigned int>
const &)>
const & lambda_create_triangulation,
155 unsigned int const global_refinements,
156 std::vector<unsigned int>
const & vector_local_refinements)
158 if(vector_local_refinements.size() != 0)
161 data.element_type == ElementType::Hypercube,
163 "Local refinements are currently only supported for meshes composed of hypercube elements."));
167 auto mesh_smoothing = dealii::Triangulation<dim>::none;
173 if(data.element_type == ElementType::Hypercube)
175 mesh_smoothing = dealii::Triangulation<dim>::limit_level_difference_at_vertices;
178 if(data.triangulation_type == TriangulationType::Serial)
180 AssertDimension(dealii::Utilities::MPI::n_mpi_processes(mpi_comm), 1);
181 triangulation = std::make_shared<dealii::Triangulation<dim>>(mesh_smoothing);
183 lambda_create_triangulation(*triangulation,
186 vector_local_refinements);
188 else if(data.triangulation_type == TriangulationType::Distributed)
190 typename dealii::parallel::distributed::Triangulation<dim>::Settings distributed_settings;
192 if(construct_multigrid_hierarchy)
194 distributed_settings =
195 dealii::parallel::distributed::Triangulation<dim>::construct_multigrid_hierarchy;
199 std::make_shared<dealii::parallel::distributed::Triangulation<dim>>(mpi_comm,
201 distributed_settings);
203 lambda_create_triangulation(*triangulation,
206 vector_local_refinements);
208 else if(data.triangulation_type == TriangulationType::FullyDistributed)
210 auto const serial_grid_generator = [&](dealii::Triangulation<dim, dim> & tria_serial) {
211 lambda_create_triangulation(tria_serial,
214 vector_local_refinements);
217 auto const serial_grid_partitioner = [&](dealii::Triangulation<dim, dim> & tria_serial,
219 unsigned int const group_size) {
221 if(data.partitioning_type == PartitioningType::Metis)
223 dealii::GridTools::partition_triangulation(dealii::Utilities::MPI::n_mpi_processes(comm),
226 else if(data.partitioning_type == PartitioningType::z_order)
228 dealii::GridTools::partition_triangulation_zorder(
229 dealii::Utilities::MPI::n_mpi_processes(comm), tria_serial);
233 AssertThrow(
false, dealii::ExcNotImplemented());
237 unsigned int const group_size = 1;
239 typename dealii::TriangulationDescription::Settings triangulation_description_setting =
240 dealii::TriangulationDescription::default_setting;
242 if(construct_multigrid_hierarchy)
244 triangulation_description_setting =
245 dealii::TriangulationDescription::construct_multigrid_hierarchy;
249 std::make_shared<dealii::parallel::fullydistributed::Triangulation<dim>>(mpi_comm);
251 auto const description = dealii::TriangulationDescription::Utilities::
252 create_description_from_triangulation_in_groups<dim, dim>(
253 serial_grid_generator,
254 serial_grid_partitioner,
255 triangulation->get_mpi_communicator(),
258 triangulation_description_setting);
260 triangulation->create_triangulation(description);
264 AssertThrow(
false, dealii::ExcMessage(
"Invalid parameter triangulation_type."));
281create_coarse_triangulations_automatically_from_fine_triangulation(
282 dealii::Triangulation<dim>
const & fine_triangulation,
283 PeriodicFacePairs<dim>
const & fine_periodic_face_pairs,
284 std::vector<std::shared_ptr<dealii::Triangulation<dim>
const>> & coarse_triangulations_const,
285 std::vector<PeriodicFacePairs<dim>> & coarse_periodic_face_pairs,
286 GridData
const & data)
290 AssertThrow(data.triangulation_type == TriangulationType::Serial or
291 data.triangulation_type == TriangulationType::Distributed,
292 dealii::ExcMessage(
"Invalid parameter triangulation_type."));
294 if(data.triangulation_type == TriangulationType::Serial)
297 fine_triangulation.all_reference_cells_are_hyper_cube(),
299 "The create_geometric_coarsening_sequence function of dealii does currently not support "
300 "simplicial elements."));
302 coarse_triangulations_const =
303 dealii::MGTransferGlobalCoarseningTools::create_geometric_coarsening_sequence(
306 else if(data.triangulation_type == TriangulationType::Distributed)
309 fine_triangulation.all_reference_cells_are_hyper_cube(),
311 "dealii::parallel::distributed::Triangulation does not support simplicial elements."));
313 coarse_triangulations_const =
314 dealii::MGTransferGlobalCoarseningTools::create_geometric_coarsening_sequence(
316 BalancedGranularityPartitionPolicy<dim>(
317 dealii::Utilities::MPI::n_mpi_processes(fine_triangulation.get_mpi_communicator())));
321 AssertThrow(
false, dealii::ExcMessage(
"Invalid parameter triangulation_type."));
327 coarse_triangulations_const.pop_back();
329 coarse_periodic_face_pairs.resize(coarse_triangulations_const.size());
330 for(
unsigned int level = 0; level < coarse_periodic_face_pairs.size(); ++level)
332 coarse_periodic_face_pairs[level] = fine_periodic_face_pairs;
338create_coarse_triangulations_for_fully_distributed_triangulation(
339 dealii::Triangulation<dim>
const & fine_triangulation,
340 std::vector<std::shared_ptr<dealii::Triangulation<dim>
const>> & coarse_triangulations_const,
341 std::vector<PeriodicFacePairs<dim>> & coarse_periodic_face_pairs,
342 GridData
const & data,
343 std::function<
void(dealii::Triangulation<dim> &,
344 PeriodicFacePairs<dim> &,
346 std::vector<unsigned int>
const &)>
const & lambda_create_triangulation,
347 std::vector<unsigned int>
const vector_local_refinements)
352 AssertThrow(data.triangulation_type == TriangulationType::FullyDistributed,
353 dealii::ExcMessage(
"Invalid parameter triangulation_type."));
355 if(fine_triangulation.n_global_levels() >= 2)
358 std::vector<std::shared_ptr<dealii::Triangulation<dim>>> coarse_triangulations =
359 std::vector<std::shared_ptr<dealii::Triangulation<dim>>>(
360 fine_triangulation.n_global_levels() - 1);
362 coarse_periodic_face_pairs = std::vector<PeriodicFacePairs<dim>>(coarse_triangulations.size());
365 unsigned int level = fine_triangulation.n_global_levels() - 2;
366 std::vector<unsigned int>
refine_local = vector_local_refinements;
369 if(data.n_refine_global >= 1)
371 unsigned int const n_refine_global_start = (
unsigned int)(data.n_refine_global - 1);
372 for(
int refine_global = n_refine_global_start; refine_global >= 0; --refine_global)
374 GridUtilities::create_triangulation<dim>(coarse_triangulations[level],
375 coarse_periodic_face_pairs[level],
376 fine_triangulation.get_mpi_communicator(),
379 lambda_create_triangulation,
395 for(
size_t material_id = 0; material_id <
refine_local.size(); material_id++)
403 GridUtilities::create_triangulation<dim>(coarse_triangulations[level],
404 coarse_periodic_face_pairs[level],
405 fine_triangulation.get_mpi_communicator(),
408 lambda_create_triangulation,
422 "There occurred a logical error when creating the geometric coarsening sequence."));
425 for(
auto const & it : coarse_triangulations)
427 coarse_triangulations_const.push_back(it);
434create_coarse_triangulations(
435 dealii::Triangulation<dim>
const & fine_triangulation,
436 PeriodicFacePairs<dim>
const & fine_periodic_face_pairs,
437 std::vector<std::shared_ptr<dealii::Triangulation<dim>
const>> & coarse_triangulations_const,
438 std::vector<PeriodicFacePairs<dim>> & coarse_periodic_face_pairs,
439 GridData
const & data,
440 std::function<
void(dealii::Triangulation<dim> &,
441 PeriodicFacePairs<dim> &,
443 std::vector<unsigned int>
const &)>
const & lambda_create_triangulation,
444 std::vector<unsigned int>
const vector_local_refinements)
449 if(data.triangulation_type == TriangulationType::Serial or
450 data.triangulation_type == TriangulationType::Distributed)
452 create_coarse_triangulations_automatically_from_fine_triangulation(fine_triangulation,
453 fine_periodic_face_pairs,
454 coarse_triangulations_const,
455 coarse_periodic_face_pairs,
458 else if(data.triangulation_type == TriangulationType::FullyDistributed)
460 create_coarse_triangulations_for_fully_distributed_triangulation(fine_triangulation,
461 coarse_triangulations_const,
462 coarse_periodic_face_pairs,
464 lambda_create_triangulation,
465 vector_local_refinements);
469 AssertThrow(
false, dealii::ExcMessage(
"Invalid parameter triangulation_type."));
483 MPI_Comm
const & mpi_comm,
484 GridData
const & data,
485 std::function<
void(dealii::Triangulation<dim> &,
486 PeriodicFacePairs<dim> &,
488 std::vector<unsigned int>
const &)>
const & lambda_create_triangulation,
489 std::vector<unsigned int>
const vector_local_refinements)
491 GridUtilities::create_triangulation(grid.triangulation,
492 grid.periodic_face_pairs,
496 lambda_create_triangulation,
497 data.n_refine_global,
498 vector_local_refinements);
508create_triangulation_with_multigrid(
510 MPI_Comm
const & mpi_comm,
511 GridData
const & data,
512 bool const involves_h_multigrid,
513 std::function<
void(dealii::Triangulation<dim> &,
514 PeriodicFacePairs<dim> &,
516 std::vector<unsigned int>
const &)>
const & lambda_create_triangulation,
517 std::vector<unsigned int>
const vector_local_refinements)
519 if(involves_h_multigrid)
522 if(data.element_type == ElementType::Simplex)
524 AssertThrow(data.create_coarse_triangulations ==
true,
526 "You need to set GridData::create_coarse_triangulations = true "
527 "in order to use h-multigrid for simplex meshes."));
531 GridUtilities::create_triangulation(grid.triangulation,
532 grid.periodic_face_pairs,
535 not data.create_coarse_triangulations,
536 lambda_create_triangulation,
537 data.n_refine_global,
538 vector_local_refinements);
541 if(grid.triangulation->has_hanging_nodes())
543 AssertThrow(data.create_coarse_triangulations ==
true,
545 "You need to set GridData::create_coarse_triangulations = true "
546 "in order to use h-multigrid for meshes with hanging nodes."));
550 if(data.create_coarse_triangulations)
552 GridUtilities::create_coarse_triangulations(*grid.triangulation,
553 grid.periodic_face_pairs,
554 grid.coarse_triangulations,
555 grid.coarse_periodic_face_pairs,
557 lambda_create_triangulation,
558 vector_local_refinements);
565 GridUtilities::create_triangulation<dim>(
566 grid, mpi_comm, data, lambda_create_triangulation, vector_local_refinements);
576create_coarse_triangulations_after_coarsening_and_refinement(
577 dealii::Triangulation<dim>
const & fine_triangulation,
578 PeriodicFacePairs<dim>
const & fine_periodic_face_pairs,
579 std::vector<std::shared_ptr<dealii::Triangulation<dim>
const>> & coarse_triangulations_const,
580 std::vector<PeriodicFacePairs<dim>> & coarse_periodic_face_pairs,
581 GridData
const & data,
582 bool const amr_preserves_boundary_cells)
584 if(data.triangulation_type == TriangulationType::Serial or
585 data.triangulation_type == TriangulationType::Distributed)
588 if(fine_periodic_face_pairs.size() > 0)
590 AssertThrow(amr_preserves_boundary_cells,
592 "Combination of adaptive mesh refinement and periodic face pairs"
593 " requires boundary cells to be preserved."));
596 create_coarse_triangulations_automatically_from_fine_triangulation(fine_triangulation,
597 fine_periodic_face_pairs,
598 coarse_triangulations_const,
599 coarse_periodic_face_pairs,
602 else if(data.triangulation_type == TriangulationType::FullyDistributed)
605 dealii::ExcMessage(
"Combination of adaptive mesh refinement and "
606 "TriangulationType::FullyDistributed not implemented."));
610 AssertThrow(
false, dealii::ExcMessage(
"Invalid parameter triangulation_type."));
620read_external_triangulation(dealii::Triangulation<dim, dim> & tria, GridData
const & data)
622 AssertThrow(not data.file_name.empty(),
624 "You are trying to read a grid file, but the string, which is supposed to contain"
625 " the file name, is empty."));
627 dealii::GridIn<dim> grid_in;
629 grid_in.attach_triangulation(tria);
632 std::string extension = data.file_name.substr(data.file_name.find_last_of(
'.') + 1);
634 AssertThrow(not extension.empty(),
635 dealii::ExcMessage(
"You are trying to read a grid file, but the file extension is"
639 typename dealii::GridIn<dim>::Format format;
640 if(extension ==
"e" || extension ==
"exo")
641 format = dealii::GridIn<dim>::Format::exodusii;
643 format = grid_in.parse_format(extension);
648 grid_in.read(data.file_name, format);
651 dealii::ExcMessage(
"You are trying to read a grid file, but the element type of the"
652 " external grid file and the element type specified in GridData"
653 " don't match. Most likely, you forgot to change the element_type"
654 " parameter of GridData to the desired element type."));
ElementType get_element_type(dealii::Triangulation< dim > const &tria)
Definition grid_data.h:70
void refine_local(dealii::Triangulation< dim > &tria, std::vector< unsigned int > const &vector_local_refinements)
Definition perform_local_refinements.h:43