Skip to content

Commit

Permalink
Remove refine option distribute and ghost_mode in favor of an exp…
Browse files Browse the repository at this point in the history
…licit partitioner
  • Loading branch information
schnellerhase committed Sep 17, 2024
1 parent 873fac5 commit e1ed42a
Show file tree
Hide file tree
Showing 9 changed files with 434 additions and 128 deletions.
67 changes: 31 additions & 36 deletions cpp/dolfinx/refinement/refine.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,46 +17,40 @@
#include <optional>
#include <utility>

#include "dolfinx/graph/AdjacencyList.h"
#include "dolfinx/mesh/Mesh.h"
#include "dolfinx/mesh/Topology.h"
#include "dolfinx/mesh/cell_types.h"
#include "dolfinx/mesh/utils.h"

#include "interval.h"
#include "plaza.h"

namespace dolfinx::refinement
{
namespace impl
{
/// @brief create the refined mesh by optionally redistributing it
template <std::floating_point T>
mesh::Mesh<T>
create_refined_mesh(const mesh::Mesh<T>& mesh,
const graph::AdjacencyList<std::int64_t>& cell_adj,
std::span<const T> new_vertex_coords,
std::array<std::size_t, 2> xshape, bool redistribute,
mesh::GhostMode ghost_mode)

// TODO: move to cpp?
inline graph::AdjacencyList<std::int32_t> maintain_coarse_partitioner(
MPI_Comm comm, int, const std::vector<mesh::CellType>& cell_types,
const std::vector<std::span<const std::int64_t>>& cell_topology)
{
if (dolfinx::MPI::size(mesh.comm()) == 1)
{
// No parallel construction necessary, i.e. redistribute also has no
// effect
return mesh::create_mesh(mesh.comm(), cell_adj.array(),
mesh.geometry().cmap(), new_vertex_coords, xshape,
ghost_mode);
}
else
{
// Let partition handle the parallel construction of the mesh
return partition<T>(mesh, cell_adj, new_vertex_coords, xshape, redistribute,
ghost_mode);
}
std::int32_t mpi_rank = MPI::rank(comm);
std::int32_t num_cell_vertices = mesh::num_cell_vertices(cell_types.front());
std::int32_t num_cells = cell_topology.front().size() / num_cell_vertices;
std::vector<std::int32_t> destinations(num_cells, mpi_rank);
std::vector<std::int32_t> dest_offsets(num_cells + 1);
std::iota(dest_offsets.begin(), dest_offsets.end(), 0);
return graph::AdjacencyList(std::move(destinations), std::move(dest_offsets));
}
} // namespace impl

/// @brief Refine with markers, optionally redistributing, and
/// optionally calculating the parent-child relationships.
///
/// @param[in] mesh Input mesh to be refined
/// @param[in] edges Optional indices of the edges that should be split
/// by this refinement, if optional is not set, a uniform refinement is
/// performed, same behavior as passing a list of all indices.
/// @param[in] redistribute Flag to call the Mesh Partitioner to
/// redistribute after refinement.
/// @param[in] ghost_mode Ghost mode of the refined mesh.
/// @param[in] edges Optional indices of the edges that should be split by this
/// refinement, if optional is not set, a uniform refinement is performend, same
/// behavior as passing a list of all indices.
/// @param[in] partitioner partitioner to be used for the refined mesh
/// @param[in] option Control the computation of parent facets, parent
/// cells. If an option is unselected, an empty list is returned.
/// @return New Mesh and optional parent cell index, parent facet
Expand All @@ -65,8 +59,8 @@ template <std::floating_point T>
std::tuple<mesh::Mesh<T>, std::optional<std::vector<std::int32_t>>,
std::optional<std::vector<std::int8_t>>>
refine(const mesh::Mesh<T>& mesh,
std::optional<std::span<const std::int32_t>> edges, bool redistribute,
mesh::GhostMode ghost_mode = mesh::GhostMode::shared_facet,
std::optional<std::span<const std::int32_t>> edges,
mesh::CellPartitionFunction partitioner = maintain_coarse_partitioner,
Option option = Option::none)
{
auto topology = mesh.topology();
Expand All @@ -80,9 +74,10 @@ refine(const mesh::Mesh<T>& mesh,
= oned ? interval::compute_refinement_data(mesh, edges, option)
: plaza::compute_refinement_data(mesh, edges, option);

mesh::Mesh<T> refined_mesh = impl::create_refined_mesh(
mesh, cell_adj, std::span<const T>(new_vertex_coords), xshape,
redistribute, ghost_mode);
mesh::Mesh<T> refined_mesh
= mesh::create_mesh(mesh.comm(), mesh.comm(), std::move(cell_adj).array(),
mesh.geometry().cmap(), mesh.comm(),
std::move(new_vertex_coords), xshape, partitioner);

// Report the number of refined cellse
const int D = topology->dim();
Expand Down
45 changes: 0 additions & 45 deletions cpp/dolfinx/refinement/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,51 +264,6 @@ create_new_vertices(MPI_Comm comm,
xshape};
}

/// Use vertex and topology data to partition new mesh across
/// processes
/// @param[in] old_mesh
/// @param[in] cell_topology Topology of cells, (vertex indices)
/// @param[in] new_coords New coordinates, row-major storage
/// @param[in] xshape The shape of `new_coords`
/// @param[in] redistribute Call graph partitioner if true
/// @param[in] ghost_mode None or shared_facet
/// @return New mesh
template <std::floating_point T>
mesh::Mesh<T> partition(const mesh::Mesh<T>& old_mesh,
const graph::AdjacencyList<std::int64_t>& cell_topology,
std::span<const T> new_coords,
std::array<std::size_t, 2> xshape, bool redistribute,
mesh::GhostMode ghost_mode)
{
if (redistribute)
{
return mesh::create_mesh(old_mesh.comm(), cell_topology.array(),
old_mesh.geometry().cmap(), new_coords, xshape,
ghost_mode);
}
else
{
auto partitioner
= [](MPI_Comm comm, int, const std::vector<mesh::CellType>& cell_types,
const std::vector<std::span<const std::int64_t>>& cell_topology)
{
std::int32_t mpi_rank = MPI::rank(comm);
std::int32_t num_cell_vertices
= mesh::num_cell_vertices(cell_types.front());
std::int32_t num_cells = cell_topology.front().size() / num_cell_vertices;
std::vector<std::int32_t> destinations(num_cells, mpi_rank);
std::vector<std::int32_t> dest_offsets(num_cells + 1);
std::iota(dest_offsets.begin(), dest_offsets.end(), 0);
return graph::AdjacencyList(std::move(destinations),
std::move(dest_offsets));
};

return mesh::create_mesh(old_mesh.comm(), old_mesh.comm(),
cell_topology.array(), old_mesh.geometry().cmap(),
old_mesh.comm(), new_coords, xshape, partitioner);
}
}

/// @brief Given an index map, add "n" extra indices at the end of local range
///
/// @note The returned global indices (local and ghosts) are adjust for the
Expand Down
7 changes: 4 additions & 3 deletions cpp/test/mesh/refinement/interval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ TEMPLATE_TEST_CASE("Interval uniform refinement",

// TODO: parent_facet
auto [refined_mesh, parent_edge, parent_facet] = refinement::refine(
mesh, std::nullopt, false, mesh::GhostMode::shared_facet,
mesh, std::nullopt, &refinement::maintain_coarse_partitioner,
refinement::Option::parent_cell);

std::vector<T> expected_x = {
Expand Down Expand Up @@ -114,7 +114,8 @@ TEMPLATE_TEST_CASE("Interval adaptive refinement",
std::vector<std::int32_t> edges{1};
// TODO: parent_facet
auto [refined_mesh, parent_edge, parent_facet] = refinement::refine(
mesh, std::span(edges), false, mesh::GhostMode::shared_facet,
mesh, std::span(edges),
mesh::create_cell_partitioner(mesh::GhostMode::shared_facet),
refinement::Option::parent_cell);

std::vector<T> expected_x = {
Expand Down Expand Up @@ -192,7 +193,7 @@ TEMPLATE_TEST_CASE("Interval Refinement (parallel)",

// TODO: parent_facet
auto [refined_mesh, parent_edges, parent_facet] = refinement::refine(
mesh, std::nullopt, false, mesh::GhostMode::shared_facet,
mesh, std::nullopt, &refinement::maintain_coarse_partitioner,
refinement::Option::parent_cell);

T rank_d = static_cast<T>(rank);
Expand Down
6 changes: 3 additions & 3 deletions cpp/test/mesh/refinement/rectangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@ plotter.show()
// plaza requires the edges to be pre initialized!
mesh.topology()->create_entities(1);

auto [mesh_fine, parent_cell, parent_facet]
= refinement::refine(mesh, std::nullopt, false, mesh::GhostMode::none,
refinement::Option::parent_cell_and_facet);
auto [mesh_fine, parent_cell, parent_facet] = refinement::refine(
mesh, std::nullopt, mesh::create_cell_partitioner(mesh::GhostMode::none),
refinement::Option::parent_cell_and_facet);

// vertex layout:
// 8---7---5
Expand Down
Loading

0 comments on commit e1ed42a

Please sign in to comment.