17 #include <deal.II/base/mpi.templates.h>
31 #include <type_traits>
36 #ifdef DEAL_II_WITH_MPI
41 template <
int dim,
int spacedim>
43 const MPI_Comm &mpi_communicator,
44 const typename ::Triangulation<dim, spacedim>::MeshSmoothing
46 const bool allow_artificial_cells,
52 , allow_artificial_cells(allow_artificial_cells)
54 const auto partition_settings =
58 (void)partition_settings;
64 ExcMessage(
"Settings must contain exactly one type of the active "
65 "cell partitioning scheme."));
69 ExcMessage(
"construct_multigrid_hierarchy requires "
70 "allow_artificial_cells to be set to true."));
75 template <
int dim,
int spacedim>
84 template <
int dim,
int spacedim>
91 const unsigned int max_active_cells =
96 "A parallel::shared::Triangulation needs to be refined in the same "
97 "way on all processors, but the participating processors don't "
98 "agree on the number of active cells."));
101 auto partition_settings = (partition_zoltan | partition_metis |
102 partition_zorder | partition_custom_signal) &
104 if (partition_settings == partition_auto)
105 # ifdef DEAL_II_TRILINOS_WITH_ZOLTAN
106 partition_settings = partition_zoltan;
107 # elif defined DEAL_II_WITH_METIS
108 partition_settings = partition_metis;
110 partition_settings = partition_zorder;
113 if (partition_settings == partition_zoltan)
115 # ifndef DEAL_II_TRILINOS_WITH_ZOLTAN
118 "Choosing 'partition_zoltan' requires the library "
119 "to be compiled with support for Zoltan! "
120 "Instead, you might use 'partition_auto' to select "
121 "a partitioning algorithm that is supported "
122 "by your current configuration."));
128 else if (partition_settings == partition_metis)
130 # ifndef DEAL_II_WITH_METIS
133 "Choosing 'partition_metis' requires the library "
134 "to be compiled with support for METIS! "
135 "Instead, you might use 'partition_auto' to select "
136 "a partitioning algorithm that is supported "
137 "by your current configuration."));
144 else if (partition_settings == partition_zorder)
148 else if (partition_settings == partition_custom_signal)
160 !(
settings & partition_custom_signal))
168 cell = this->begin_active(),
171 if (allow_artificial_cells)
183 active_halo_layer_vector =
186 std::set<typename parallel::shared::Triangulation<dim, spacedim>::
187 active_cell_iterator>
188 active_halo_layer(active_halo_layer_vector.begin(),
189 active_halo_layer_vector.end());
191 for (
unsigned int index = 0; cell != endc; cell++, index++)
194 true_subdomain_ids_of_cells[index] = cell->subdomain_id();
196 if (cell->is_locally_owned() ==
false &&
197 active_halo_layer.find(cell) == active_halo_layer.end())
204 true_level_subdomain_ids_of_cells.resize(this->n_levels());
210 for (
unsigned int lvl = 0; lvl < this->n_levels(); ++lvl)
212 true_level_subdomain_ids_of_cells[lvl].resize(
218 level_halo_layer_vector =
220 *
this, predicate, lvl);
223 level_halo_layer(level_halo_layer_vector.begin(),
224 level_halo_layer_vector.end());
227 cell_iterator cell = this->
begin(lvl),
228 endc = this->
end(lvl);
229 for (
unsigned int index = 0; cell != endc; cell++, index++)
233 true_level_subdomain_ids_of_cells[lvl][index] =
234 cell->level_subdomain_id();
243 if (cell->is_active() &&
244 cell->subdomain_id() !=
249 if (cell->has_children())
251 bool keep_cell =
false;
252 for (
unsigned int c = 0;
253 c < GeometryInfo<dim>::max_children_per_cell;
255 if (cell->child(c)->level_subdomain_id() ==
267 if (!cell->is_locally_owned_on_level() &&
268 level_halo_layer.find(cell) != level_halo_layer.
end())
272 cell->set_level_subdomain_id(
281 for (
unsigned int index = 0; cell != endc; cell++, index++)
282 true_subdomain_ids_of_cells[index] = cell->subdomain_id();
288 const unsigned int n_my_cells = std::count_if(
289 this->begin_active(),
292 [](
const auto &i) {
return (i.is_locally_owned()); });
294 const unsigned int total_cells =
297 ExcMessage(
"Not all cells are assigned to a processor."));
302 if (
settings & construct_multigrid_hierarchy)
304 const unsigned int n_my_cells =
305 std::count_if(this->
begin(), this->
end(), [](
const auto &i) {
306 return (i.is_locally_owned_on_level());
310 const unsigned int total_cells =
313 ExcMessage(
"Not all cells are assigned to a processor."));
320 template <
int dim,
int spacedim>
324 return allow_artificial_cells;
329 template <
int dim,
int spacedim>
330 const std::vector<types::subdomain_id> &
333 return true_subdomain_ids_of_cells;
338 template <
int dim,
int spacedim>
339 const std::vector<types::subdomain_id> &
341 const unsigned int level)
const
343 Assert(
level < true_level_subdomain_ids_of_cells.size(),
345 Assert(true_level_subdomain_ids_of_cells[
level].size() ==
348 return true_level_subdomain_ids_of_cells[
level];
353 template <
int dim,
int spacedim>
369 using int_type = std::underlying_type_t<
371 static_assert(
sizeof(
int_type) ==
sizeof(std::uint8_t),
372 "Internal type mismatch.");
374 std::vector<int_type> refinement_configurations(this->
n_active_cells() *
377 for (
const auto &cell : this->active_cell_iterators())
378 if (cell->is_locally_owned())
380 refinement_configurations[cell->active_cell_index() * 2 + 0] =
381 static_cast<int_type>(cell->refine_flag_set());
382 refinement_configurations[cell->active_cell_index() * 2 + 1] =
383 static_cast<int_type>(cell->coarsen_flag_set() ? 1 : 0);
387 this->get_communicator(),
388 refinement_configurations);
390 for (
const auto &cell : this->active_cell_iterators())
392 cell->clear_refine_flag();
393 cell->clear_coarsen_flag();
396 (refinement_configurations[cell->active_cell_index() * 2 + 0] >
400 refinement_configurations[cell->active_cell_index() * 2 +
404 "Refinement/coarsening flags of cells are not consistent in parallel!"));
406 if (refinement_configurations[cell->active_cell_index() * 2 + 0] !=
409 refinement_configurations[cell->active_cell_index() * 2 + 0]));
411 if (refinement_configurations[cell->active_cell_index() * 2 + 1] >
413 cell->set_coarsen_flag();
419 this->update_number_cache();
424 template <
int dim,
int spacedim>
437 const typename ::Triangulation<dim, spacedim>::DistortedCellList
445 this->update_number_cache();
450 template <
int dim,
int spacedim>
456 (void)construction_data;
463 template <
int dim,
int spacedim>
466 const ::Triangulation<dim, spacedim> &other_tria)
470 const ::parallel::DistributedTriangulationBase<dim, spacedim>
471 *
>(&other_tria) ==
nullptr),
473 "Cannot use this function on parallel::distributed::Triangulation."));
478 this->update_number_cache();
489 template <
int dim,
int spacedim>
497 template <
int dim,
int spacedim>
504 template <
int dim,
int spacedim>
505 const std::vector<unsigned int> &
509 return true_subdomain_ids_of_cells;
514 template <
int dim,
int spacedim>
515 const std::vector<unsigned int> &
517 const unsigned int)
const
520 return true_level_subdomain_ids_of_cells;
536 template <
int dim,
int spacedim>
548 const std::vector<types::subdomain_id> &true_subdomain_ids =
552 for (
const auto &cell :
shared_tria->active_cell_iterators())
554 const unsigned int index = cell->active_cell_index();
556 cell->set_subdomain_id(true_subdomain_ids[
index]);
563 template <
int dim,
int spacedim>
567 if (shared_tria && shared_tria->with_artificial_cells())
570 for (
const auto &cell : shared_tria->active_cell_iterators())
572 const unsigned int index = cell->active_cell_index();
573 cell->set_subdomain_id(saved_subdomain_ids[
index]);
583 #include "shared_tria.inst"
virtual void create_triangulation(const std::vector< Point< spacedim >> &vertices, const std::vector< CellData< dim >> &cells, const SubCellData &subcelldata)
cell_iterator end() const
virtual void execute_coarsening_and_refinement()
std::vector< unsigned int > saved_subdomain_ids
const SmartPointer< const ::parallel::shared::Triangulation< dim, spacedim > > shared_tria
~TemporarilyRestoreSubdomainIds()
TemporarilyRestoreSubdomainIds(const Triangulation< dim, spacedim > &tria)
types::subdomain_id my_subdomain
virtual void copy_triangulation(const ::Triangulation< dim, spacedim > &old_tria) override
virtual void execute_coarsening_and_refinement() override
typename ::Triangulation< dim, spacedim >::active_cell_iterator active_cell_iterator
virtual void copy_triangulation(const ::Triangulation< dim, spacedim > &other_tria) override
const std::vector< types::subdomain_id > & get_true_subdomain_ids_of_cells() const
Triangulation(const MPI_Comm &mpi_communicator, const typename ::Triangulation< dim, spacedim >::MeshSmoothing=(::Triangulation< dim, spacedim >::none), const bool allow_artificial_cells=false, const Settings settings=partition_auto)
typename ::Triangulation< dim, spacedim >::cell_iterator cell_iterator
@ partition_custom_signal
@ construct_multigrid_hierarchy
bool with_artificial_cells() const
const std::vector< types::subdomain_id > & get_true_level_subdomain_ids_of_cells(const unsigned int level) const
virtual void create_triangulation(const std::vector< Point< spacedim >> &vertices, const std::vector< CellData< dim >> &cells, const SubCellData &subcelldata) override
virtual bool is_multilevel_hierarchy_constructed() const override
const bool allow_artificial_cells
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
__global__ void set(Number *val, const Number s, const size_type N)
static ::ExceptionBase & ExcInternalError()
#define Assert(cond, exc)
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
@ construct_multigrid_hierarchy
VectorType::value_type * begin(VectorType &V)
VectorType::value_type * end(VectorType &V)
T sum(const T &t, const MPI_Comm &mpi_communicator)
T max(const T &t, const MPI_Comm &mpi_communicator)
unsigned int n_active_cells(const internal::TriangulationImplementation::NumberCache< 1 > &c)
unsigned int n_cells(const internal::TriangulationImplementation::NumberCache< 1 > &c)
const types::subdomain_id artificial_subdomain_id
const TriangulationDescription::Settings settings
const ::Triangulation< dim, spacedim > & tria