Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Let hp::Refinement::choose_p_over_h() communicate future FE indices and refinement flags on all types of parallel Triangulation. #16759

Merged
merged 4 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions doc/news/changes/minor/20240318Fehling
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Changed: hp::Refinement::choose_p_over_h() now communicates
refinement flags and future FE indices on ghost cells for
all types of parallel Triangulation objects to decide between
p- and h-refinement.
<br>
(Marc Fehling, 2024/03/18)
28 changes: 24 additions & 4 deletions include/deal.II/distributed/tria.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,8 @@

DEAL_II_NAMESPACE_OPEN

#ifdef DEAL_II_WITH_P4EST

// Forward declarations
# ifndef DOXYGEN
#ifndef DOXYGEN

namespace FETools
{
Expand All @@ -77,7 +75,28 @@ namespace parallel
class TemporarilyMatchRefineFlags;
}
} // namespace parallel
# endif

namespace internal
{
namespace parallel
{
namespace distributed
{
namespace TriangulationImplementation
{
template <int dim, int spacedim>
void
exchange_refinement_flags(
dealii::parallel::distributed::Triangulation<dim, spacedim> &);
}
} // namespace distributed
} // namespace parallel
} // namespace internal
#endif



#ifdef DEAL_II_WITH_P4EST

namespace parallel
{
Expand Down Expand Up @@ -1096,6 +1115,7 @@ namespace parallel
#endif



namespace parallel
{
namespace distributed
Expand Down
2 changes: 1 addition & 1 deletion include/deal.II/dofs/dof_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -1782,7 +1782,7 @@ namespace internal
* @note This function can only be called on direct parent cells, i.e.,
* non-active cells whose children are all active.
*
* @note On parallel::shared::Triangulation objects where sibling cells
* @note On parallel Triangulation objects where sibling cells
* can be ghost cells, make sure that future FE indices have been properly
* communicated with communicate_future_fe_indices() first. Otherwise,
* results might differ on different processors. There is no check for
Expand Down
90 changes: 55 additions & 35 deletions source/distributed/tria.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,59 @@
DEAL_II_NAMESPACE_OPEN


namespace internal
{
namespace parallel
{
namespace distributed
{
namespace TriangulationImplementation
{
/**
* Communicate refinement flags on ghost cells from the owner of the
* cell.
*
* This is necessary to get consistent refinement, as mesh smoothing
* would undo some of the requested coarsening/refinement.
*/
template <int dim, int spacedim>
void
exchange_refinement_flags(
dealii::parallel::distributed::Triangulation<dim, spacedim> &tria)
{
auto pack =
[](const typename Triangulation<dim, spacedim>::active_cell_iterator
&cell) -> std::uint8_t {
if (cell->refine_flag_set())
return 1;
if (cell->coarsen_flag_set())
return 2;
return 0;
};

auto unpack =
[](const typename Triangulation<dim, spacedim>::active_cell_iterator
&cell,
const std::uint8_t &flag) -> void {
cell->clear_coarsen_flag();
cell->clear_refine_flag();
if (flag == 1)
cell->set_refine_flag();
else if (flag == 2)
cell->set_coarsen_flag();
};

GridTools::exchange_cell_data_to_ghosts<std::uint8_t>(tria,
pack,
unpack);
}
} // namespace TriangulationImplementation
} // namespace distributed
} // namespace parallel
} // namespace internal



#ifdef DEAL_II_WITH_P4EST

namespace
Expand Down Expand Up @@ -563,40 +616,6 @@ namespace
cell->set_subdomain_id(ghost_owner);
}
}
template <int dim, int spacedim>
void
exchange_refinement_flags(Triangulation<dim, spacedim> &tria)
{
// Communicate refinement flags on ghost cells from the owner of the
// cell. This is necessary to get consistent refinement, as mesh
// smoothing would undo some of the requested coarsening/refinement.

auto pack =
[](
const typename Triangulation<dim, spacedim>::active_cell_iterator &cell)
-> std::uint8_t {
if (cell->refine_flag_set())
return 1;
if (cell->coarsen_flag_set())
return 2;
return 0;
};
auto unpack =
[](
const typename Triangulation<dim, spacedim>::active_cell_iterator &cell,
const std::uint8_t &flag) -> void {
cell->clear_coarsen_flag();
cell->clear_refine_flag();
if (flag == 1)
cell->set_refine_flag();
else if (flag == 2)
cell->set_coarsen_flag();
};

GridTools::exchange_cell_data_to_ghosts<std::uint8_t,
Triangulation<dim, spacedim>>(
tria, pack, unpack);
}

# ifdef P4EST_SEARCH_LOCAL
template <int dim>
Expand Down Expand Up @@ -2776,7 +2795,8 @@ namespace parallel
// First exchange coarsen/refinement flags on ghost cells. After this
// collective communication call all flags on ghost cells match the
// flags set by the user on the owning rank.
exchange_refinement_flags(*this);
dealii::internal::parallel::distributed::TriangulationImplementation::
exchange_refinement_flags(*this);

// Now we can call the sequential version to apply mesh smoothing and
// other modifications:
Expand Down
19 changes: 19 additions & 0 deletions source/distributed/tria.inst.in
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,23 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS)
#endif
\}
\}

namespace internal
\{
namespace parallel
\{
namespace distributed
\{
namespace TriangulationImplementation
\{
#if deal_II_dimension <= deal_II_space_dimension
template void
exchange_refinement_flags(
dealii::parallel::distributed::
Triangulation<deal_II_dimension, deal_II_space_dimension> &);
#endif
\}
\}
\}
\}
}
22 changes: 14 additions & 8 deletions source/dofs/dof_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1658,7 +1658,7 @@ namespace internal
"You ask for information on children of this cell which is only "
"available for active cells. One of its children is not active."));

// Ghost siblings might occur on parallel::shared::Triangulation
// Ghost siblings might occur on parallel Triangulation
// objects. The public interface does not allow to access future
// FE indices on ghost cells. However, we need this information
// here and thus call the internal function that does not check
Expand Down Expand Up @@ -2770,11 +2770,6 @@ void DoFHandler<dim, spacedim>::connect_to_triangulation_signals()
}));

// refinement signals
this->tria_listeners_for_transfer.push_back(
this->tria->signals.pre_refinement.connect([this]() {
internal::hp::DoFHandlerImplementation::Implementation::
communicate_future_fe_indices(*this);
}));
this->tria_listeners_for_transfer.push_back(
this->tria->signals.pre_refinement.connect(
[this]() { this->pre_transfer_action(); }));
Expand Down Expand Up @@ -2893,6 +2888,9 @@ void DoFHandler<dim, spacedim>::pre_transfer_action()

this->active_fe_index_transfer = std::make_unique<ActiveFEIndexTransfer>();

internal::hp::DoFHandlerImplementation::Implementation::
communicate_future_fe_indices(*this);

dealii::internal::hp::DoFHandlerImplementation::Implementation::
collect_fe_indices_on_cells_to_be_refined(*this);
}
Expand Down Expand Up @@ -2930,10 +2928,18 @@ void DoFHandler<dim, spacedim>::pre_distributed_transfer_action()
active_fe_index_transfer->active_fe_indices.resize(
get_triangulation().n_active_cells(), numbers::invalid_fe_index);

// Collect future FE indices on locally owned and ghost cells.
// The public interface does not allow to access future FE indices
// on ghost cells. However, we need this information here and thus
// call the internal function that does not check for cell ownership.
internal::hp::DoFHandlerImplementation::Implementation::
communicate_future_fe_indices(*this);

for (const auto &cell : active_cell_iterators())
if (cell->is_locally_owned())
if (cell->is_artificial() == false)
active_fe_index_transfer->active_fe_indices[cell->active_cell_index()] =
cell->future_fe_index();
dealii::internal::DoFCellAccessorImplementation::Implementation::
future_fe_index<dim, spacedim, false>(*cell);

// Create transfer object and attach to it.
const auto *distributed_tria =
Expand Down
82 changes: 37 additions & 45 deletions source/hp/refinement.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include <deal.II/distributed/grid_refinement.h>
#include <deal.II/distributed/shared_tria.h>
#include <deal.II/distributed/tria.h>
#include <deal.II/distributed/tria_base.h>

#include <deal.II/dofs/dof_accessor.templates.h>
Expand Down Expand Up @@ -704,17 +705,29 @@ namespace hp
Assert(dof_handler.has_hp_capabilities(),
(typename DoFHandler<dim, spacedim>::ExcOnlyAvailableWithHP()));

// Ghost siblings might occur on parallel::shared::Triangulation objects.
// We need information about future FE indices on all locally relevant
// cells here, and thus communicate them.
if (dynamic_cast<const parallel::shared::Triangulation<dim, spacedim> *>(
&dof_handler.get_triangulation()) != nullptr)
internal::hp::DoFHandlerImplementation::communicate_future_fe_indices(
const_cast<DoFHandler<dim, spacedim> &>(dof_handler));
// Ghost siblings might occur on parallel Triangulation objects.
// We need information about refinement flags and future FE indices
// on all locally relevant cells here, and thus communicate them.
if (dealii::parallel::distributed::Triangulation<dim, spacedim> *tria =
dynamic_cast<
dealii::parallel::distributed::Triangulation<dim, spacedim> *>(
const_cast<dealii::Triangulation<dim, spacedim> *>(
&dof_handler.get_triangulation())))
{
dealii::internal::parallel::distributed::TriangulationImplementation::
exchange_refinement_flags(*tria);
}

internal::hp::DoFHandlerImplementation::communicate_future_fe_indices(
const_cast<DoFHandler<dim, spacedim> &>(dof_handler));

// Now: choose p-adaptation over h-adaptation.
for (const auto &cell : dof_handler.active_cell_iterators())
if (cell->is_locally_owned() && cell->future_fe_index_set())
{
// This cell is flagged for p-adaptation.

// Remove any h-refinement flags.
cell->clear_refine_flag();

// A cell will only be coarsened into its parent if all of its
Expand All @@ -740,43 +753,22 @@ namespace hp
{
if (child->is_active())
{
if (child->is_locally_owned())
{
if (child->coarsen_flag_set())
++h_flagged_children;
if (child->future_fe_index_set())
++p_flagged_children;
}
else if (child->is_ghost())
{
// The case of siblings being owned by different
// processors can only occur for
// parallel::shared::Triangulation objects.
Assert(
(dynamic_cast<const parallel::shared::
Triangulation<dim, spacedim> *>(
&dof_handler.get_triangulation()) != nullptr),
ExcInternalError());

if (child->coarsen_flag_set())
++h_flagged_children;
// The public interface does not allow to access
// future FE indices on ghost cells. However, we
// need this information here and thus call the
// internal function that does not check for cell
// ownership.
if (internal::DoFCellAccessorImplementation::
Implementation::
future_fe_index_set<dim, spacedim, false>(
*child))
++p_flagged_children;
}
else
{
// Siblings of locally owned cells are all
// either also locally owned or ghost cells.
DEAL_II_ASSERT_UNREACHABLE();
}
Assert(child->is_artificial() == false,
ExcInternalError());

if (child->coarsen_flag_set())
++h_flagged_children;

// The public interface does not allow to access
// future FE indices on ghost cells. However, we
// need this information here and thus call the
// internal function that does not check for cell
// ownership.
if (internal::DoFCellAccessorImplementation::
Implementation::
future_fe_index_set<dim, spacedim, false>(
*child))
++p_flagged_children;
}
}

Expand All @@ -796,7 +788,7 @@ namespace hp
}
else
{
// Perform p-adaptation on all children and
// Perform p-adaptation (if scheduled) and
// drop all h-coarsening flags.
for (const auto &child : parent->child_iterators())
{
Expand Down