11#include "graphbuild.h"
12#include <basix/mdspan.hpp>
14#include <dolfinx/graph/AdjacencyList.h>
15#include <dolfinx/graph/ordering.h>
16#include <dolfinx/graph/partition.h>
26class ElementDofLayout;
46 std::span<const std::int32_t> nodemap)
49 std::vector<T> data(list.
array());
50 std::vector<std::int32_t> offsets(list.
offsets().size());
54 for (std::size_t n = 0; n < nodemap.size(); ++n)
55 offsets[nodemap[n] + 1] = list.
num_links(n);
56 for (std::size_t n = nodemap.size(); n < (std::size_t)list.
num_nodes(); ++n)
58 std::partial_sum(offsets.begin(), offsets.end(), offsets.begin());
61 for (std::size_t n = 0; n < nodemap.size(); ++n)
63 auto links_old = list.
links(n);
64 auto links_new = list_new.links(nodemap[n]);
65 assert(links_old.size() == links_new.size());
66 std::copy(links_old.begin(), links_old.end(), links_new.begin());
88template <std::
floating_po
int T>
89std::tuple<std::vector<std::int32_t>, std::vector<T>, std::vector<std::int32_t>>
91 std::span<const std::int32_t> facets)
95 const int tdim = topology->dim();
98 throw std::runtime_error(
99 "Cannot use mesh::locate_entities_boundary (boundary) for cells.");
105 std::vector<std::int32_t> vertices, entities;
107 auto f_to_v = topology->connectivity(tdim - 1, 0);
109 auto f_to_e = topology->connectivity(tdim - 1, dim);
111 for (
auto f : facets)
113 auto v = f_to_v->links(f);
114 vertices.insert(vertices.end(), v.begin(), v.end());
115 auto e = f_to_e->links(f);
116 entities.insert(entities.end(), e.begin(), e.end());
120 std::sort(vertices.begin(), vertices.end());
121 vertices.erase(std::unique(vertices.begin(), vertices.end()),
123 std::sort(entities.begin(), entities.end());
124 entities.erase(std::unique(entities.begin(), entities.end()),
129 auto x_dofmap = mesh.
geometry().dofmap();
130 std::span<const T> x_nodes = mesh.
geometry().x();
135 auto v_to_c = topology->connectivity(0, tdim);
137 auto c_to_v = topology->connectivity(tdim, 0);
139 std::vector<T> x_vertices(3 * vertices.size(), -1.0);
140 std::vector<std::int32_t> vertex_to_pos(v_to_c->num_nodes(), -1);
141 for (std::size_t i = 0; i < vertices.size(); ++i)
143 const std::int32_t v = vertices[i];
146 const int c = v_to_c->links(v).front();
147 auto cell_vertices = c_to_v->links(c);
148 auto it = std::find(cell_vertices.begin(), cell_vertices.end(), v);
149 assert(it != cell_vertices.end());
150 const int local_pos = std::distance(cell_vertices.begin(), it);
152 auto dofs = MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE::
153 submdspan(x_dofmap, c, MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent);
154 for (std::size_t j = 0; j < 3; ++j)
155 x_vertices[j * vertices.size() + i] = x_nodes[3 * dofs[local_pos] + j];
156 vertex_to_pos[v] = i;
159 return {std::move(entities), std::move(x_vertices), std::move(vertex_to_pos)};
194 MPI_Comm comm,
int nparts,
int tdim,
218template <std::
floating_po
int T>
219std::vector<T>
h(
const Mesh<T>& mesh, std::span<const std::int32_t> entities,
222 if (entities.empty())
223 return std::vector<T>();
225 return std::vector<T>(entities.size(), 0);
228 const std::vector<std::int32_t> vertex_xdofs
230 assert(!entities.empty());
231 const std::size_t num_vertices = vertex_xdofs.size() / entities.size();
234 std::span<const T> x = mesh.
geometry().x();
237 auto delta_norm = [](
const auto& p0,
const auto& p1)
240 for (std::size_t i = 0; i < 3; ++i)
241 norm += (p0[i] - p1[i]) * (p0[i] - p1[i]);
242 return std::sqrt(norm);
247 std::vector<T>
h(entities.size(), 0);
248 for (std::size_t e = 0; e < entities.size(); ++e)
251 std::span<const std::int32_t> e_vertices(
252 vertex_xdofs.data() + e * num_vertices, num_vertices);
255 for (std::size_t i = 0; i < e_vertices.size(); ++i)
257 std::span<const T, 3> p0(x.data() + 3 * e_vertices[i], 3);
258 for (std::size_t j = i + 1; j < e_vertices.size(); ++j)
260 std::span<const T, 3> p1(x.data() + 3 * e_vertices[j], 3);
261 h[e] = std::max(
h[e], delta_norm(p0, p1));
272template <std::
floating_po
int T>
274 std::span<const std::int32_t> entities)
279 if (entities.empty())
280 return std::vector<T>();
282 if (topology->cell_types().size() > 1)
283 throw std::runtime_error(
"Mixed topology not supported");
284 if (topology->cell_types()[0] == CellType::prism and dim == 2)
285 throw std::runtime_error(
"More work needed for prism cell");
287 const int gdim = mesh.
geometry().dim();
291 std::span<const T> x = mesh.
geometry().x();
295 if (topology->cell_types()[0] == CellType::tetrahedron)
298 std::vector<std::int32_t> geometry_entities
301 const std::size_t shape1 = geometry_entities.size() / entities.size();
302 std::vector<T> n(entities.size() * 3);
305 case CellType::interval:
308 throw std::invalid_argument(
"Interval cell normal undefined in 3D");
309 for (std::size_t i = 0; i < entities.size(); ++i)
312 std::array vertices{geometry_entities[i * shape1],
313 geometry_entities[i * shape1 + 1]};
314 std::array p = {std::span<const T, 3>(x.data() + 3 * vertices[0], 3),
315 std::span<const T, 3>(x.data() + 3 * vertices[1], 3)};
319 std::transform(p[1].begin(), p[1].end(), p[0].begin(), t.begin(),
320 [](
auto x,
auto y) { return x - y; });
322 T norm = std::sqrt(t[0] * t[0] + t[1] * t[1]);
323 std::span<T, 3> ni(n.data() + 3 * i, 3);
324 ni[0] = -t[1] / norm;
330 case CellType::triangle:
332 for (std::size_t i = 0; i < entities.size(); ++i)
335 std::array vertices = {geometry_entities[i * shape1 + 0],
336 geometry_entities[i * shape1 + 1],
337 geometry_entities[i * shape1 + 2]};
338 std::array p = {std::span<const T, 3>(x.data() + 3 * vertices[0], 3),
339 std::span<const T, 3>(x.data() + 3 * vertices[1], 3),
340 std::span<const T, 3>(x.data() + 3 * vertices[2], 3)};
343 std::array<T, 3> dp1, dp2;
344 std::transform(p[1].begin(), p[1].end(), p[0].begin(), dp1.begin(),
345 [](
auto x,
auto y) { return x - y; });
346 std::transform(p[2].begin(), p[2].end(), p[0].begin(), dp2.begin(),
347 [](
auto x,
auto y) { return x - y; });
350 std::array<T, 3> ni = math::cross(dp1, dp2);
351 T norm = std::sqrt(ni[0] * ni[0] + ni[1] * ni[1] + ni[2] * ni[2]);
352 std::transform(ni.begin(), ni.end(), std::next(n.begin(), 3 * i),
353 [norm](
auto x) { return x / norm; });
358 case CellType::quadrilateral:
361 for (std::size_t i = 0; i < entities.size(); ++i)
364 std::array vertices = {geometry_entities[i * shape1 + 0],
365 geometry_entities[i * shape1 + 1],
366 geometry_entities[i * shape1 + 2]};
367 std::array p = {std::span<const T, 3>(x.data() + 3 * vertices[0], 3),
368 std::span<const T, 3>(x.data() + 3 * vertices[1], 3),
369 std::span<const T, 3>(x.data() + 3 * vertices[2], 3)};
372 std::array<T, 3> dp1, dp2;
373 std::transform(p[1].begin(), p[1].end(), p[0].begin(), dp1.begin(),
374 [](
auto x,
auto y) { return x - y; });
375 std::transform(p[2].begin(), p[2].end(), p[0].begin(), dp2.begin(),
376 [](
auto x,
auto y) { return x - y; });
379 std::array<T, 3> ni = math::cross(dp1, dp2);
380 T norm = std::sqrt(ni[0] * ni[0] + ni[1] * ni[1] + ni[2] * ni[2]);
381 std::transform(ni.begin(), ni.end(), std::next(n.begin(), 3 * i),
382 [norm](
auto x) { return x / norm; });
388 throw std::invalid_argument(
389 "cell_normal not supported for this cell type.");
396template <std::
floating_po
int T>
398 std::span<const std::int32_t> entities)
400 if (entities.empty())
401 return std::vector<T>();
403 std::span<const T> x = mesh.
geometry().x();
407 const std::vector<std::int32_t> e_to_g
409 std::size_t shape1 = e_to_g.size() / entities.size();
411 std::vector<T> x_mid(entities.size() * 3, 0);
412 for (std::size_t e = 0; e < entities.size(); ++e)
414 std::span<T, 3> p(x_mid.data() + 3 * e, 3);
415 std::span<const std::int32_t> rows(e_to_g.data() + e * shape1, shape1);
416 for (
auto row : rows)
418 std::span<const T, 3> xg(x.data() + 3 * row, 3);
419 std::transform(p.begin(), p.end(), xg.begin(), p.begin(),
420 [size = rows.size()](
auto x,
auto y)
421 { return x + y / size; });
434template <std::
floating_po
int T>
435std::pair<std::vector<T>, std::array<std::size_t, 2>>
440 const int tdim = topology->dim();
446 auto x_dofmap = mesh.
geometry().dofmap();
447 const std::int32_t num_vertices = topology->index_map(0)->size_local()
448 + topology->index_map(0)->num_ghosts();
449 auto c_to_v = topology->connectivity(tdim, 0);
451 std::vector<std::int32_t> vertex_to_node(num_vertices);
452 for (
int c = 0; c < c_to_v->num_nodes(); ++c)
455 = MDSPAN_IMPL_STANDARD_NAMESPACE::MDSPAN_IMPL_PROPOSED_NAMESPACE::
456 submdspan(x_dofmap, c, MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent);
457 auto vertices = c_to_v->links(c);
458 for (std::size_t i = 0; i < vertices.size(); ++i)
459 vertex_to_node[vertices[i]] = x_dofs[i];
463 std::span<const T> x_nodes = mesh.
geometry().x();
464 std::vector<T> x_vertices(3 * vertex_to_node.size(), 0.0);
465 for (std::size_t i = 0; i < vertex_to_node.size(); ++i)
467 const int pos = 3 * vertex_to_node[i];
468 for (std::size_t j = 0; j < 3; ++j)
469 x_vertices[j * vertex_to_node.size() + i] = x_nodes[pos + j];
472 return {std::move(x_vertices), {3, vertex_to_node.size()}};
478template <
typename Fn,
typename T>
480 std::vector<std::int8_t>, Fn,
481 MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
482 const T, MDSPAN_IMPL_STANDARD_NAMESPACE::extents<
484 MDSPAN_IMPL_STANDARD_NAMESPACE::dynamic_extent>>>::value;
499template <std::
floating_po
int T, MarkerFn<T> U>
503 using cmdspan3x_t = MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
505 MDSPAN_IMPL_STANDARD_NAMESPACE::extents<
506 std::size_t, 3, MDSPAN_IMPL_STANDARD_NAMESPACE::dynamic_extent>>;
509 const auto [xdata, xshape] = impl::compute_vertex_coords(mesh);
510 cmdspan3x_t x(xdata.data(), xshape);
511 const std::vector<std::int8_t> marked = marker(x);
512 if (marked.size() != x.extent(1))
513 throw std::runtime_error(
"Length of array of markers is wrong.");
517 const int tdim = topology->dim();
526 auto e_to_v = topology->connectivity(dim, 0);
528 std::vector<std::int32_t> entities;
529 for (
int e = 0; e < e_to_v->num_nodes(); ++e)
532 bool all_vertices_marked =
true;
533 for (std::int32_t v : e_to_v->links(e))
537 all_vertices_marked =
false;
542 if (all_vertices_marked)
543 entities.push_back(e);
572template <std::
floating_po
int T, MarkerFn<T> U>
578 const int tdim = topology->dim();
581 throw std::runtime_error(
582 "Cannot use mesh::locate_entities_boundary (boundary) for cells.");
588 const std::vector<std::int32_t> boundary_facets
591 using cmdspan3x_t = MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
593 MDSPAN_IMPL_STANDARD_NAMESPACE::extents<
594 std::size_t, 3, MDSPAN_IMPL_STANDARD_NAMESPACE::dynamic_extent>>;
597 const auto [facet_entities, xdata, vertex_to_pos]
598 = impl::compute_vertex_coords_boundary(mesh, dim, boundary_facets);
599 cmdspan3x_t x(xdata.data(), 3, xdata.size() / 3);
600 const std::vector<std::int8_t> marked = marker(x);
601 if (marked.size() != x.extent(1))
602 throw std::runtime_error(
"Length of array of markers is wrong.");
606 auto e_to_v = topology->connectivity(dim, 0);
608 std::vector<std::int32_t> entities;
609 for (
auto e : facet_entities)
612 bool all_vertices_marked =
true;
613 for (
auto v : e_to_v->links(e))
615 const std::int32_t pos = vertex_to_pos[v];
618 all_vertices_marked =
false;
624 if (all_vertices_marked)
625 entities.push_back(e);
647template <std::
floating_po
int T>
648std::vector<std::int32_t>
650 std::span<const std::int32_t> entities,
bool orient)
655 if (topology->cell_types().size() > 1)
656 throw std::runtime_error(
"Mixed topology not supported");
657 CellType cell_type = topology->cell_types()[0];
658 if (cell_type == CellType::prism and dim == 2)
659 throw std::runtime_error(
"More work needed for prism cells");
660 if (orient and (cell_type != CellType::tetrahedron or dim != 2))
661 throw std::runtime_error(
"Can only orient facets of a tetrahedral mesh");
664 auto x = geometry.
x();
666 const int tdim = topology->dim();
672 auto xdofs = geometry.
dofmap();
673 auto e_to_c = topology->connectivity(dim, tdim);
676 throw std::runtime_error(
677 "Entity-to-cell connectivity has not been computed.");
680 auto e_to_v = topology->connectivity(dim, 0);
683 throw std::runtime_error(
684 "Entity-to-vertex connectivity has not been computed.");
687 auto c_to_v = topology->connectivity(tdim, 0);
690 throw std::runtime_error(
691 "Cell-to-vertex connectivity has not been computed.");
694 const std::size_t num_vertices
696 std::vector<std::int32_t> geometry_idx(entities.size() * num_vertices);
697 for (std::size_t i = 0; i < entities.size(); ++i)
699 const std::int32_t idx = entities[i];
701 const std::int32_t cell = e_to_c->links(idx).back();
702 auto ev = e_to_v->links(idx);
703 assert(ev.size() == num_vertices);
704 auto cv = c_to_v->links(cell);
705 std::span<const std::int32_t> xc(
706 xdofs.data_handle() + xdofs.extent(1) * cell, xdofs.extent(1));
707 for (std::size_t j = 0; j < num_vertices; ++j)
709 int k = std::distance(cv.begin(), std::find(cv.begin(), cv.end(), ev[j]));
710 assert(k < (
int)cv.size());
711 geometry_idx[i * num_vertices + j] = xc[k];
717 std::array<T, 3> midpoint = {0, 0, 0};
718 for (std::int32_t j : xc)
719 for (
int k = 0; k < 3; ++k)
720 midpoint[k] += x[3 * j + k];
721 std::transform(midpoint.begin(), midpoint.end(), midpoint.begin(),
722 [size = xc.size()](
auto x) { return x / size; });
725 std::array<T, 3> p0, p1, p2;
726 std::copy_n(std::next(x.begin(), 3 * geometry_idx[i * num_vertices + 0]),
728 std::copy_n(std::next(x.begin(), 3 * geometry_idx[i * num_vertices + 1]),
730 std::copy_n(std::next(x.begin(), 3 * geometry_idx[i * num_vertices + 2]),
734 std::transform(midpoint.begin(), midpoint.end(), p0.begin(), a.begin(),
735 [](
auto x,
auto y) { return x - y; });
736 std::transform(p1.begin(), p1.end(), p0.begin(), std::next(a.begin(), 3),
737 [](
auto x,
auto y) { return x - y; });
738 std::transform(p2.begin(), p2.end(), p0.begin(), std::next(a.begin(), 6),
739 [](
auto x,
auto y) { return x - y; });
743 if (math::det(a.data(), {3, 3}) > 0.0)
745 std::swap(geometry_idx[i * num_vertices + 1],
746 geometry_idx[i * num_vertices + 2]);
759 = mesh::GhostMode::none,
770std::vector<std::int32_t>
772 std::span<const std::int32_t> entities,
int d0,
783 typename std::remove_reference_t<typename U::value_type>>>& elements,
784 const U& x, std::array<std::size_t, 2> xshape,
790 auto build_topology = [](
auto comm,
auto& elements,
auto& dof_layout,
791 auto& cells,
auto& partitioner)
808 const int tdim =
cell_dim(elements[0].cell_shape());
812 std::vector<std::int64_t> original_cell_index0;
813 std::vector<int> ghost_owners;
824 std::vector<int> src;
825 std::tie(cell_nodes, src, original_cell_index0, ghost_owners)
832 std::vector<std::int32_t>(cells.num_nodes(), rank), 1);
834 std::int64_t offset(0), num_owned(cells.num_nodes());
835 MPI_Exscan(&num_owned, &offset, 1, MPI_INT64_T, MPI_SUM, comm);
836 original_cell_index0.resize(cell_nodes.
num_nodes());
837 std::iota(original_cell_index0.begin(), original_cell_index0.end(),
852 const std::int32_t num_owned_cells
853 = cells_extracted.
num_nodes() - ghost_owners.size();
855 auto [graph, unmatched_facets, max_v, facet_attached_cells]
857 std::span<const std::int64_t>(
858 cells_extracted.
array().data(),
859 cells_extracted.
offsets()[num_owned_cells]),
860 std::span<const std::int32_t>(cells_extracted.
offsets().data(),
861 num_owned_cells + 1),
867 std::vector<std::int64_t> original_cell_index(original_cell_index0.size());
868 for (std::size_t i = 0; i < remap.size(); ++i)
869 original_cell_index[remap[i]] = original_cell_index0[i];
870 std::copy_n(std::next(original_cell_index0.cbegin(), num_owned_cells),
872 std::next(original_cell_index.begin(), num_owned_cells));
873 cells_extracted = reorder_list(cells_extracted, remap);
874 cell_nodes = reorder_list(cell_nodes, remap);
879 std::vector<std::int64_t> boundary_vertices(unmatched_facets);
880 std::sort(boundary_vertices.begin(), boundary_vertices.end());
881 boundary_vertices.erase(
882 std::unique(boundary_vertices.begin(), boundary_vertices.end()),
883 boundary_vertices.end());
886 if (boundary_vertices.size() > 0 and boundary_vertices[0] == -1)
887 boundary_vertices.erase(boundary_vertices.begin());
893 std::vector<std::int32_t> cell_group_offsets
894 = {0, std::int32_t(cells_extracted.
num_nodes() - ghost_owners.size()),
896 std::vector<mesh::CellType> cell_type = {elements[0].cell_shape()};
897 return std::pair{
create_topology(comm, cells_extracted, original_cell_index,
898 ghost_owners, cell_type,
899 cell_group_offsets, boundary_vertices),
900 std::move(cell_nodes)};
903 auto [topology, cell_nodes]
904 = build_topology(comm, elements, dof_layout, cells, partitioner);
908 int tdim = topology.dim();
909 for (
int e = 1; e < tdim; ++e)
912 topology.create_entities(e);
915 if (elements[0].needs_dof_permutations())
916 topology.create_entity_permutations();
921 comm, std::make_shared<Topology>(std::move(topology)),
922 std::move(geometry));
945Mesh<typename std::remove_reference_t<typename U::value_type>>
948 std::remove_reference_t<typename U::value_type>>>& elements,
949 const U& x, std::array<std::size_t, 2> xshape,
GhostMode ghost_mode)
952 return create_mesh(comm, cells, elements, x, xshape,
nullptr);
955 return create_mesh(comm, cells, elements, x, xshape,
968template <std::
floating_po
int T>
969std::tuple<Mesh<T>, std::vector<std::int32_t>, std::vector<std::int32_t>,
970 std::vector<std::int32_t>>
972 std::span<const std::int32_t> entities)
976 auto [topology, subentity_to_entity, subvertex_to_vertex]
980 const int tdim = mesh.
topology()->dim();
987 return {
Mesh<T>(mesh.
comm(), std::make_shared<Topology>(std::move(topology)),
988 std::move(geometry)),
989 std::move(subentity_to_entity), std::move(subvertex_to_vertex),
990 std::move(subx_to_x_dofmap)};
A CoordinateElement manages coordinate mappings for isoparametric cells.
Definition CoordinateElement.h:39
The class represents the degree-of-freedom (dofs) for an element. Dofs are associated with a mesh ent...
Definition ElementDofLayout.h:31
int num_entity_dofs(int dim) const
Return the number of dofs for a given entity dimension.
Definition ElementDofLayout.cpp:63
This class provides a static adjacency list data structure. It is commonly used to store directed gra...
Definition AdjacencyList.h:28
int num_links(std::size_t node) const
Number of connections for given node.
Definition AdjacencyList.h:102
std::span< T > links(std::size_t node)
Get the links (edges) for given node.
Definition AdjacencyList.h:112
const std::vector< T > & array() const
Return contiguous array of links for all nodes (const version)
Definition AdjacencyList.h:129
std::int32_t num_nodes() const
Get the number of nodes.
Definition AdjacencyList.h:97
const std::vector< std::int32_t > & offsets() const
Offset for each node in array() (const version)
Definition AdjacencyList.h:135
Geometry stores the geometry imposed on a mesh.
Definition Geometry.h:33
MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan< const std::int32_t, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents< std::size_t, 2 > > dofmap() const
DOF map.
Definition Geometry.h:94
std::span< const value_type > x() const
Access geometry degrees-of-freedom data (const version).
Definition Geometry.h:113
A Mesh consists of a set of connected and numbered mesh topological entities, and geometry data.
Definition Mesh.h:23
std::shared_ptr< Topology > topology_mutable() const
Get mesh topology if one really needs the mutable version.
Definition Mesh.h:72
std::shared_ptr< Topology > topology()
Get mesh topology.
Definition Mesh.h:64
Geometry< T > & geometry()
Get mesh geometry.
Definition Mesh.h:76
MPI_Comm comm() const
Mesh MPI communicator.
Definition Mesh.h:84
Requirements on function for geometry marking.
Definition utils.h:479
std::tuple< std::vector< std::int32_t >, std::vector< T >, std::vector< std::int32_t > > compute_vertex_coords_boundary(const mesh::Mesh< T > &mesh, int dim, std::span< const std::int32_t > facets)
The coordinates of 'vertices' for for entities of a give dimension that are attached to specified fac...
Definition utils.h:90
std::pair< std::vector< T >, std::array< std::size_t, 2 > > compute_vertex_coords(const mesh::Mesh< T > &mesh)
The coordinates for all 'vertices' in the mesh.
Definition utils.h:436
int size(MPI_Comm comm)
Return size of the group (number of processes) associated with the communicator.
Definition MPI.cpp:72
int rank(MPI_Comm comm)
Return process rank for the communicator.
Definition MPI.cpp:64
Finite element method functionality.
Definition assemble_matrix_impl.h:25
std::tuple< graph::AdjacencyList< std::int64_t >, std::vector< int >, std::vector< std::int64_t >, std::vector< int > > distribute(MPI_Comm comm, const graph::AdjacencyList< std::int64_t > &list, const graph::AdjacencyList< std::int32_t > &destinations)
Distribute adjacency list nodes to destination ranks.
Definition partition.cpp:38
std::vector< std::int32_t > reorder_gps(const graph::AdjacencyList< std::int32_t > &graph)
Re-order a graph using the Gibbs-Poole-Stockmeyer algorithm.
Definition ordering.cpp:360
std::function< graph::AdjacencyList< std::int32_t >(MPI_Comm, int, const AdjacencyList< std::int64_t > &, bool)> partition_fn
Signature of functions for computing the parallel partitioning of a distributed graph.
Definition partition.h:36
AdjacencyList< std::int32_t > partition_graph(MPI_Comm comm, int nparts, const AdjacencyList< std::int64_t > &local_graph, bool ghosting)
Partition graph across processes using the default graph partitioner.
Definition partition.cpp:21
AdjacencyList< typename std::decay_t< U >::value_type > regular_adjacency_list(U &&data, int degree)
Construct a constant degree (valency) adjacency list.
Definition AdjacencyList.h:183
Mesh data structures and algorithms on meshes.
Definition DofMap.h:32
mesh::Geometry< typename std::remove_reference_t< typename U::value_type > > create_geometry(MPI_Comm comm, const Topology &topology, const std::vector< fem::CoordinateElement< std::remove_reference_t< typename U::value_type > > > &elements, const graph::AdjacencyList< std::int64_t > &cell_nodes, const U &x, int dim, std::function< std::vector< int >(const graph::AdjacencyList< std::int32_t > &)> reorder_fn=nullptr)
Build Geometry from input data.
Definition Geometry.h:179
std::pair< mesh::Geometry< T >, std::vector< int32_t > > create_subgeometry(const Topology &topology, const Geometry< T > &geometry, int dim, std::span< const std::int32_t > subentity_to_entity)
Create a sub-geometry for a subset of entities.
Definition Geometry.h:280
Topology create_topology(MPI_Comm comm, const graph::AdjacencyList< std::int64_t > &cells, std::span< const std::int64_t > original_cell_index, std::span< const int > ghost_owners, const std::vector< CellType > &cell_type, const std::vector< std::int32_t > &cell_group_offsets, std::span< const std::int64_t > boundary_vertices)
Create a distributed mesh topology.
Definition Topology.cpp:892
GhostMode
Enum for different partitioning ghost modes.
Definition utils.h:35
std::function< graph::AdjacencyList< std::int32_t >(MPI_Comm comm, int nparts, int tdim, const graph::AdjacencyList< std::int64_t > &cells)> CellPartitionFunction
Signature for the cell partitioning function. The function should compute the destination rank for ce...
Definition utils.h:195
std::vector< T > cell_normals(const Mesh< T > &mesh, int dim, std::span< const std::int32_t > entities)
Compute normal to given cell (viewed as embedded in 3D)
Definition utils.h:273
int cell_dim(CellType type)
Return topological dimension of cell type.
Definition cell_types.cpp:134
CellType cell_entity_type(CellType type, int d, int index)
Return type of cell for entity of dimension d at given entity index.
Definition cell_types.cpp:64
std::tuple< Topology, std::vector< int32_t >, std::vector< int32_t > > create_subtopology(const Topology &topology, int dim, std::span< const std::int32_t > entities)
Create a topology for a subset of entities of a given topological dimension.
Definition Topology.cpp:1157
std::vector< std::int32_t > locate_entities_boundary(const Mesh< T > &mesh, int dim, U marker)
Compute indices of all mesh entities that are attached to an owned boundary facet and evaluate to tru...
Definition utils.h:573
int num_cell_vertices(CellType type)
Number vertices for a cell type.
Definition cell_types.cpp:147
std::tuple< graph::AdjacencyList< std::int32_t >, std::vector< std::int64_t >, std::size_t, std::vector< std::int32_t > > build_local_dual_graph(std::span< const std::int64_t > cells, std::span< const std::int32_t > offsets, int tdim)
Compute the local part of the dual graph (cell-cell connections via facets) and facet with only one a...
Definition graphbuild.cpp:391
std::vector< T > h(const Mesh< T > &mesh, std::span< const std::int32_t > entities, int dim)
Compute greatest distance between any two vertices of the mesh entities (h).
Definition utils.h:219
Mesh< typename std::remove_reference_t< typename U::value_type > > create_mesh(MPI_Comm comm, const graph::AdjacencyList< std::int64_t > &cells, const std::vector< fem::CoordinateElement< typename std::remove_reference_t< typename U::value_type > > > &elements, const U &x, std::array< std::size_t, 2 > xshape, CellPartitionFunction partitioner)
Create a mesh using a provided mesh partitioning function.
Definition utils.h:780
graph::AdjacencyList< std::int64_t > extract_topology(const CellType &cell_type, const fem::ElementDofLayout &layout, const graph::AdjacencyList< std::int64_t > &cells)
Extract topology from cell data, i.e. extract cell vertices.
Definition utils.cpp:28
std::vector< std::int32_t > locate_entities(const Mesh< T > &mesh, int dim, U marker)
Compute indices of all mesh entities that evaluate to true for the provided geometric marking functio...
Definition utils.h:500
std::vector< std::int32_t > entities_to_geometry(const Mesh< T > &mesh, int dim, std::span< const std::int32_t > entities, bool orient)
Determine the indices in the geometry data for each vertex of the given mesh entities.
Definition utils.h:649
std::vector< std::int32_t > exterior_facet_indices(const Topology &topology)
Compute the indices of all exterior facets that are owned by the caller.
Definition utils.cpp:55
std::vector< std::int32_t > compute_incident_entities(const Topology &topology, std::span< const std::int32_t > entities, int d0, int d1)
Compute incident indices.
Definition utils.cpp:105
CellType
Cell type identifier.
Definition cell_types.h:22
std::vector< T > compute_midpoints(const Mesh< T > &mesh, int dim, std::span< const std::int32_t > entities)
Compute the midpoints for mesh entities of a given dimension.
Definition utils.h:397
std::tuple< Mesh< T >, std::vector< std::int32_t >, std::vector< std::int32_t >, std::vector< std::int32_t > > create_submesh(const Mesh< T > &mesh, int dim, std::span< const std::int32_t > entities)
Create a new mesh consisting of a subset of entities in a mesh.
Definition utils.h:971
CellPartitionFunction create_cell_partitioner(mesh::GhostMode ghost_mode=mesh::GhostMode::none, const graph::partition_fn &partfn=&graph::partition_graph)
Create a function that computes destination rank for mesh cells in this rank by applying the default ...
Definition utils.cpp:84