18#include <deal.II/base/mpi.templates.h>
45 template <
int dim,
int spacedim>
58#ifndef DEAL_II_WITH_MPI
65 template <
int dim,
int spacedim>
70#ifndef DEAL_II_WITH_MPI
76 if (const ::parallel::TriangulationBase<dim, spacedim> *other_tria_x =
77 dynamic_cast<const ::parallel::TriangulationBase<dim, spacedim>
90 template <
int dim,
int spacedim>
106 template <
int dim,
int spacedim>
118 template <
int dim,
int spacedim>
129 template <
int dim,
int spacedim>
139 template <
int dim,
int spacedim>
148 template <
int dim,
int spacedim>
158 template <
int dim,
int spacedim>
167#ifdef DEAL_II_WITH_MPI
168 template <
int dim,
int spacedim>
191 for (
const auto &cell : this->active_cell_iterators())
192 if (cell->is_ghost())
193 number_cache.ghost_owners.insert(cell->subdomain_id());
195 Assert(number_cache.ghost_owners.size() <
200 if (this->n_levels() > 0)
201 number_cache.n_locally_owned_active_cells = std::count_if(
202 this->begin_active(),
205 [](
const auto &i) { return i.is_locally_owned(); });
214 this->mpi_communicator);
232 cell->level_subdomain_id() != this->locally_owned_subdomain())
234 cell->level_subdomain_id());
244 const int mpi_tag = Utilities::MPI::internal::Tags::
245 triangulation_base_fill_level_ghost_owners;
248 std::vector<MPI_Request> requests(
250 unsigned int dummy = 0;
251 unsigned int req_counter = 0;
253 for (
const auto &it : this->
number_cache.level_ghost_owners)
255 ierr = MPI_Isend(&dummy,
261 &requests[req_counter]);
266 for (
const auto &it : this->number_cache.level_ghost_owners)
269 ierr = MPI_Recv(&dummy,
274 this->mpi_communicator,
279 if (requests.size() > 0)
281 ierr = MPI_Waitall(requests.size(),
283 MPI_STATUSES_IGNORE);
287 ierr = MPI_Barrier(this->mpi_communicator);
292 Assert(this->number_cache.level_ghost_owners.size() <
297 this->number_cache.number_of_global_coarse_cells = this->
n_cells(0);
305 template <
int dim,
int spacedim>
314 template <
int dim,
int spacedim>
323 std::vector<unsigned int> reference_cells_ui;
327 reference_cells_ui.push_back(
static_cast<unsigned int>(i));
335 this->reference_cells.clear();
336 for (
const auto &i : reference_cells_ui)
337 this->reference_cells.emplace_back(
343 template <
int dim,
int spacedim>
353 template <
int dim,
int spacedim>
355 const std::set<types::subdomain_id>
363 template <
int dim,
int spacedim>
365 const std::set<types::subdomain_id>
373 template <
int dim,
int spacedim>
385 template <
int dim,
int spacedim>
397 template <
int dim,
int spacedim>
401#ifndef DEAL_II_WITH_MPI
407 if (pst->with_artificial_cells() ==
false)
413 std::vector<unsigned int> cell_counter(
n_subdomains + 1);
417 cell_counter[cell->subdomain_id() + 1]++;
421 cell_counter[i + 1] += cell_counter[i];
430 std::make_shared<const Utilities::MPI::Partitioner>(
437 cell->set_global_active_cell_index(
438 cell_counter[cell->subdomain_id()]++);
448 this->n_locally_owned_active_cells();
453 const int ierr = MPI_Exscan(
454 &n_locally_owned_cells,
459 this->mpi_communicator);
464 std::pair<types::global_cell_index, types::global_cell_index> my_range;
465 my_range.first = cell_index;
468 if (cell->is_locally_owned())
469 cell->set_global_active_cell_index(cell_index++);
473 my_range.second = cell_index;
476 std::vector<types::global_dof_index> is_ghost_vector;
479 [](
const auto &cell) {
return cell->global_active_cell_index(); },
480 [&is_ghost_vector](
const auto &cell,
const auto &id) {
481 cell->set_global_active_cell_index(
id);
482 is_ghost_vector.push_back(
id);
486 IndexSet is_local(this->n_global_active_cells());
487 is_local.add_range(my_range.first, my_range.second);
489 std::sort(is_ghost_vector.begin(), is_ghost_vector.end());
491 is_ghost.add_indices(is_ghost_vector.begin(), is_ghost_vector.end());
494 std::make_shared<const Utilities::MPI::Partitioner>(
501 std::vector<types::global_cell_index> n_cells_level(
505 if (cell->level_subdomain_id() == this->locally_owned_subdomain())
506 n_cells_level[cell->level()]++;
509 std::vector<types::global_cell_index> cell_index(
512 int ierr = MPI_Exscan(
513 n_cells_level.data(),
515 this->n_global_levels(),
518 this->mpi_communicator);
529 std::pair<types::global_cell_index, types::global_cell_index>>
532 my_ranges[l].first = cell_index[l];
535 if (cell->level_subdomain_id() == this->locally_owned_subdomain())
536 cell->set_global_level_cell_index(cell_index[cell->level()]++);
541 my_ranges[l].second = cell_index[l];
544 std::vector<std::vector<types::global_dof_index>> is_ghost_vectors(
550 [](
const auto &cell) {
return cell->global_level_cell_index(); },
551 [&is_ghost_vectors](
const auto &cell,
const auto &id) {
552 cell->set_global_level_cell_index(
id);
553 is_ghost_vectors[cell->level()].push_back(
id);
556 number_cache.level_cell_index_partitioners.resize(
557 this->n_global_levels());
560 for (
unsigned int l = 0; l < this->n_global_levels(); ++l)
562 IndexSet is_local(n_cells_level[l]);
563 is_local.add_range(my_ranges[l].first, my_ranges[l].second);
565 IndexSet is_ghost(n_cells_level[l]);
566 std::sort(is_ghost_vectors[l].begin(), is_ghost_vectors[l].end());
567 is_ghost.add_indices(is_ghost_vectors[l].begin(),
568 is_ghost_vectors[l].end());
570 number_cache.level_cell_index_partitioners[l] =
571 std::make_shared<const Utilities::MPI::Partitioner>(
572 is_local, is_ghost, this->mpi_communicator);
581 template <
int dim,
int spacedim>
584 const
std::vector<
bool> &vertex_locally_moved)
590 const std::vector<bool> locally_owned_vertices =
592 for (
unsigned int i = 0; i < locally_owned_vertices.size(); ++i)
593 Assert((vertex_locally_moved[i] ==
false) ||
594 (locally_owned_vertices[i] ==
true),
595 ExcMessage(
"The vertex_locally_moved argument must not "
596 "contain vertices that are not locally owned"));
601 for (
unsigned int d = 0; d < spacedim; ++d)
602 invalid_point[d] = std::numeric_limits<double>::quiet_NaN();
604 const auto pack = [&](
const auto &cell) {
605 std::vector<Point<spacedim>>
vertices(cell->n_vertices());
607 for (
const auto v : cell->vertex_indices())
608 if (vertex_locally_moved[cell->vertex_index(v)])
616 const auto unpack = [&](
const auto &cell,
const auto &
vertices) {
617 for (
const auto v : cell->vertex_indices())
624 std::vector<Point<spacedim>>>(
637 template <
int dim,
int spacedim>
648 template <
int dim,
int spacedim>
652 global_level_cell_index_partitioner(
const unsigned int level)
const
657 return number_cache.level_cell_index_partitioners[level];
662 template <
int dim,
int spacedim>
672 template <
int dim,
int spacedim>
687 template <
int dim,
int spacedim>
698 template <
int dim,
int spacedim>
711 const bool have_coarser_cell =
729#include "distributed/tria_base.inst"
bool is_locally_owned() const
void add_range(const size_type begin, const size_type end)
virtual void copy_triangulation(const Triangulation< dim, spacedim > &other_tria)
virtual std::size_t memory_consumption() const
virtual void update_reference_cells()
Triangulation(const MeshSmoothing smooth_grid=none, const bool check_for_distorted_cells=false)
virtual std::vector< types::boundary_id > get_boundary_ids() const
std::vector< Point< spacedim > > vertices
const bool check_for_distorted_cells
unsigned int n_active_cells() const
std::vector< ReferenceCell > reference_cells
Triangulation(const MeshSmoothing smooth_grid=none, const bool check_for_distorted_cells=false)
unsigned int n_levels() const
active_cell_iterator end_active(const unsigned int level) const
MeshSmoothing smooth_grid
active_cell_iterator begin_active(const unsigned int level=0) const
DistributedTriangulationBase(const MPI_Comm mpi_communicator, const typename ::Triangulation< dim, spacedim >::MeshSmoothing smooth_grid=(::Triangulation< dim, spacedim >::none), const bool check_for_distorted_cells=false)
virtual bool has_hanging_nodes() const override
const std::set< types::subdomain_id > & level_ghost_owners() const
virtual std::size_t memory_consumption() const override
virtual types::global_cell_index n_global_active_cells() const override
void update_reference_cells() override
const std::set< types::subdomain_id > & ghost_owners() const
types::subdomain_id n_subdomains
types::subdomain_id locally_owned_subdomain() const override
const MPI_Comm mpi_communicator
virtual unsigned int n_global_levels() const override
virtual std::vector< types::boundary_id > get_boundary_ids() const override
unsigned int n_locally_owned_active_cells() const
virtual MPI_Comm get_mpi_communicator() const override
virtual types::coarse_cell_id n_global_coarse_cells() const override
virtual bool is_multilevel_hierarchy_constructed() const=0
virtual void update_number_cache()
virtual void clear() override
std::weak_ptr< const Utilities::MPI::Partitioner > global_active_cell_index_partitioner() const override
TriangulationBase(const MPI_Comm mpi_communicator, const typename ::Triangulation< dim, spacedim >::MeshSmoothing smooth_grid=(::Triangulation< dim, spacedim >::none), const bool check_for_distorted_cells=false)
void communicate_locally_moved_vertices(const std::vector< bool > &vertex_locally_moved)
void reset_global_cell_indices()
types::subdomain_id my_subdomain
virtual void copy_triangulation(const ::Triangulation< dim, spacedim > &old_tria) override
#define DEAL_II_NAMESPACE_OPEN
constexpr bool running_in_debug_mode()
#define DEAL_II_CXX20_REQUIRES(condition)
#define DEAL_II_NAMESPACE_CLOSE
IteratorRange< active_cell_iterator > active_cell_iterators() const
IteratorRange< cell_iterator > cell_iterators() const
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcNeedsMPI()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertThrowMPI(error_code)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
TriaActiveIterator< CellAccessor< dim, spacedim > > active_cell_iterator
virtual std::vector< types::manifold_id > get_manifold_ids() const
virtual std::vector< types::manifold_id > get_manifold_ids() const override
IndexSet complete_index_set(const IndexSet::size_type N)
std::enable_if_t< std::is_fundamental_v< T >, std::size_t > memory_consumption(const T &t)
T sum(const T &t, const MPI_Comm mpi_communicator)
unsigned int n_mpi_processes(const MPI_Comm mpi_communicator)
T max(const T &t, const MPI_Comm mpi_communicator)
std::vector< T > compute_set_union(const std::vector< T > &vec, const MPI_Comm comm)
const MPI_Datatype mpi_type_id_for_type
void release_all_unused_memory()
unsigned int n_cells(const internal::TriangulationImplementation::NumberCache< 1 > &c)
constexpr ReferenceCell make_reference_cell_from_int(const std::uint8_t kind)
constexpr types::global_dof_index invalid_dof_index
constexpr types::subdomain_id artificial_subdomain_id
bool is_nan(const double x)
unsigned int subdomain_id
global_cell_index coarse_cell_id
unsigned int global_cell_index
unsigned int n_global_levels
unsigned int n_locally_owned_active_cells
types::global_cell_index n_global_active_cells
types::coarse_cell_id number_of_global_coarse_cells